Navigation

Define a Custom Query or Mutation

On this page

Overview

You can define a custom query or mutation resolver to handle complex logic beyond the basic CRUD operations supported by automatically generated queries and mutations. Custom resolvers use a field name that you define, pass arguments from the query or mutation to a function, and return the result of the function back to the caller.

Procedure

1

Create a New Custom Resolver

In the Realm UI, click GraphQL in the navigation sidebar and then select the Custom Resolvers tab.

Click the Add a Custom Resolver button to open the configuration screen for a new custom resolver.

The custom resolvers screen in the Realm UI
2

Define the Resolver Name and Type

On the configuration screen, enter a name and type for the custom resolver.

The GraphQL Field Name is the name of the field that calls the custom resolver and the Parent Type determines if the resolver is a query or a mutation.

The name and type configuration inputs of a custom query
3

Define Input and Payload Types

GraphQL is strongly typed, so if your custom query or mutation accepts an argument or returns a value you must define a JSON schema for the corresponding Input Type or Payload Type. Input and payload type schemas must be objects that include a title field and at least one property.

The Input Type corresponds to the input parameter of the custom query or mutation. If you don’t specify an input type, the custom resolver does not accept any arguments.

The Payload Type corresponds to the object returned by the custom query or mutation. If you don’t specify a payload type, the custom resolver returns a DefaultPayload that always resolves to the object {status: "complete" } regardless of the resolver function’s return value.

Example

MongoDB Realm uses the input and payload type JSON schemas to define GraphQL types for your resolver. For example, the following JSON schema and GraphQL type are equivalent:

JSON Schema
{
  "bsonType": "object",
  "title": "FlightStatusPayload",
  "required": [
     "flightNumber",
     "originAirport",
     "destinationAirport",
     "scheduledDeparture",
     "scheduledArrival"
  ],
  "properties": {
    "flightNumber": { "bsonType": "string" },
    "originAirport": { "bsonType": "string" },
    "destinationAirport": { "bsonType": "string" },
    "scheduledDeparture": { "bsonType": "date" },
    "scheduledArrival": { "bsonType": "date" },
    "isDelayed": { "bsonType": "boolean" },
  }
}
GraphQL Type
type FlightStatusPayload {
  flightNumber: String!
  originAirport: String!
  destinationAirport: String!
  scheduledDeparture: DateTime!
  scheduledArrival: DateTime!
  isDelayed: Boolean
}
4

Define the Resolver Function

When a user calls a custom query or mutation, MongoDB Realm executes the resolver function and returns the result, which must conform to the Payload Type if you defined it. If you defined an Input Type, MongoDB Realm passes the provided input argument to the resolver function.

To configure the resolver function, click the Function dropdown and either select an existing function or create a new one.

The resolver function dropdown
5

Save and Deploy the Resolver

Once you have configured the resolver, click Save and then deploy your application. Once deployed, you can call the custom resolver through the GraphQL API.

Example

A custom query named verifyUserAge accepts a person’s age and returns a boolean that is true if they’re 18 years or older.

query {
  verifyUserAge(input: { age: 42 }) {
    isOldEnough
  }
}

The query uses the following resolver function:

exports = function(input) {
  return input.age >= 18;
}

The custom query requires the caller to provide an age argument, so the resolver uses the following Input Type:

{
  "bsonType": "object",
  "title": "VerifyUserAgeInput",
  "required": ["age"],
  "properties": {
    "age": { "bsonType": "number" }
  }
}

The query returns a single field, isOldEnough, that contains a boolean, so the resolver uses the following Payload Type:

{
  "bsonType": "object",
  "title": "VerifyUserAgePayload",
  "properties": {
    "isOldEnough": { "bsonType": "boolean" }
  }
}