Nerd For Tech
Published in

Nerd For Tech

Realm GraphQL Demo: Custom Resolvers

Motivation

  1. Fixed-size for the response payload: The size of the response cannot exceed 4 MB. This limitation would prevent us from being able to query aggregated data that would require a response larger than 4 MB.
  2. Creation of different endpoints for each business logic requirement. This would not only pose a management problem, but also a maintenance problem: what if we make changes in the future? How do we manage the different versions? This model becomes more complex if we want to send parameters in the request to tailor the response to the requirements.
  1. An easier and simpler method to execute accurate endpoint calls.
  2. Easier to choose what we need in the response, alleviating the size of the response by not requiring unnecessary fields.
  3. Simpler maintenance.
  4. Avoid versioning.

What are we going to build?

  1. Having a given IMDB rating.
  2. Belonging to a set of genres.
  3. Being a certain rate.
  4. Being in several available languages.

Prerequisites

  1. Have a Cloud MongoDB account.
  2. Create a Free Tier Cluster.
  3. Configure realm-cli .
  4. Add an API-Key to be able to access using realm-cli.
  5. Load initial data into the Cluster.

Create an Atlas Account

  1. Navigate to the MongoDB Atlas login page.
  2. Click Login.
  3. Either enter a new set of user credentials or click the Sign Up with Google button.
  4. Click Sign Up to create your account.
  5. Follow the prompts to create an organization and project in your Atlas account. You can use the default suggested names or enter your own.
Account startup screenshot
Free Tier Cluster screenshot

Create a Free Atlas Cluster

  1. Log into your MongoDB Atlas account at cloud.mongodb.com.
  2. Once you’re logged into your account, Atlas should prompt you to create your first cluster. In the Shared Clusters category, click Create a Cluster. Alternatively, you can click Build a Cluster from the project view in your Atlas account.
  3. Under Cloud Provider & Region, select AWS and N. Virginia (us-east-1).
  4. Under Additional Settings, select MongoDB 4.4 from the Select a Version dropdown.
  5. Under Cluster Name, enter the name Cluster0 for your new cluster.
  6. Click the Create Cluster button at the bottom of the page.
Screenshot of a recently created cluster

Install the Realm CLI

npm install -g mongodb-realm-cli@beta
realm-cli --version

Add an API Key to Your Atlas Project & Log into the Realm CLI

  • Click Access Manager at the top of the Atlas UI. Select the Project Access option from the dropdown.
  • Navigate to the API Keys tab.
  • Click the Create API Key button.
  • In the Description text box, enter “API Key for the MongoDB Realm CLI”.
Create API key screenshot in Realm UI
  • In the Project Permissions dropdown, select “Project Owner” and deselect “Project Read Only”.
Project Permissions screenshot
  • Copy your Public API Key and save it somewhere.
  • Click Next.
  • Copy your Private API Key and save it somewhere; after leaving this page, you will no longer be able to view it via the Realm UI.
  • Click the Add Access List Entry button.
  • Click Use Current IP Address.
  • Click Save.
  • When you have safely recorded your private API key, click Done to navigate back to the Project Access Manager page.
  • Use the following command in your terminal to authenticate with the Realm CLI:
realm-cli login --api-key <public API key> --private-api-key <private API key>
you have successfully logged in as <public API key>

Load sample dataset to the Cluster

Load Sample Dataset screenshot
One document of Movie collection screenshot

Adding Rules to our collections

Rules section in Realm UI
Rules section in Realm UI
Generate Schema in Realm UI
Schema generated for the movies collection

Add an authentication provider

API Key Authentication Provider

Testing GraphQL with GraphiQL

query {
movie {
_id
}
}
db.movies.findOne({},{"_id" : 1})

Create a custom resolver

[{"$match": {
"imdb.rating": { "$gte": 7 },
"genres": { "$nin": [ "Crime", "Horror" ] } ,
"rated": { "$in": ["PG", "G" ] },
"languages": { "$all": [ "English", "Japanese" ] }
}
}]
Screenshot of Add Custom Resolver Screen in Realm
  • GraphQL Field Name: This corresponds to the name we want to use when we refer to this custom resolver in our queries.
  • Parent Type: Type of custom resolver we are creating, in our case, being a read request, we will select Query.
  • Function: Here we create the function that will be called every time a call to our custom resolver is executed. You can link an existing function or create it here.
Screenshot of the Custom Resolver editor in Realm UI
  • Input Type (Recommended): At the moment we will leave it at None. Later we will explain what we can do with it and what it is used for.
  • Payload Type (Recommended): Type of object of the response. In our case, our aggregate will return a set of movies, therefore we choose Existing Type (List) and type [Movie].
query {
oneTitleMovies {
title
}
}

Testing our newest created Custom Resolver in Postman

query {
oneTitleMovies {
title
cast
}
}
{"apiKey","{{api_key}}"}
curl --location --request POST '[your_graphql_endpoint]' \
--header 'apiKey: [your_api_key]' \
--header 'Content-Type: application/json' \
--data-raw '{"query": "query {"query oneTitleMovies {"title" {"cast", "variables":{}}'
Postman request for a GraphQL query

Add an Input Type to our Custom Resolver

  1. “imdb.rating”: { $gte: 7 }
  2. genres: { $nin: [ “Crime”, “Horror” ] } ,
  3. rated: { $in: [ “PG”, “G” ] },
  4. languages: { $all: [ “English”, “Japanese” ] } }
{
"bsonType": "object",
"title": "Filter",
"required" : [
"imdbRating",
"genres",
"rated"],
"properties": {
"imdbRating": {
"bsonType": "int"
},
"genres": {
"bsonType": "array",
"items": {
"bsonType": "string"
}
},
"rated": {
"bsonType": "array",
"items": {
"bsonType": "string"
}
},
"languages": {
"bsonType": "array",
"items": {
"bsonType": "string"
}
}
}
}
Input Type of Custom Type in Custom Resolver
query {
oneTitleMovies(input: {
imdbRating: 7
genres: [
"Crime"
"Horror"
]
rated: [
"PG"
"G"
]
languages: [
"English"
"Japanese"
]
}) {
title
}
}

Wrapping up

Download example code from GitHub

realm-cli import \
--app-id=myapp-abcde \
--path=./path/to/app/dir \
--strategy=merge \
--include-hosting \
--include-dependencies

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Josman Pérez Expóstio

If I had to sum up my professional interests in one sentence, I could only say that I am passionate about technology.