GraphQL Types, Resolvers, and Operators
On this page
- Overview
- Scalar Types
- Document Types
- Field Mapping
- BSON Type Mapping
- Input Types
- QueryInput
- InsertInput
- UpdateInput
- RelationInput
- SortByInput
- Query Resolvers
- Find a Single Document
- Find Multiple Documents
- Mutation Resolvers
- Insert a Single Document
- Insert Multiple Documents
- Update a Single Document
- Update Multiple Documents
- Upsert a Single Document
- Replace a Single Document
- Delete a Single Document
- Delete Multiple Documents
- Paginate Data
Overview
Atlas App Services automatically generates a GraphQL schema for any collection that has a defined schema. For each collection, App Services generates the following:
A document type that represents a single document in the collection
A set of queries and mutations that allow you to access and manipulate documents in the collection.
A set of input types that allow you to filter queries, modify specific fields, and sort results.
Note
Example Collection Schema
This page includes examples that demonstrate generated values based
on the following schema for a movies
collection:
{ "title": "Movie", "required": ["title"], "properties": { "_id": { "bsonType": "objectId" }, "title": { "bsonType": "string" }, "year": { "bsonType": "int" }, "rated": { "bsonType": "string" }, "runtime": { "bsonType": "int" }, "director": { "bsonType": "string" }, "reviews": { "bsonType": "array", "items": { "bsonType": "objectId" } }, "cast": { "bsonType": "array", "items": { "bsonType": "string" } } } }
Scalar Types
App Services supports all of the standard GraphQL scalar types and also generates the ObjectId
scalar.
The following scalar types are supported:
Document Types
App Services generates a single GraphQL type for the
documents in a collection based on the collection schema. The type uses the name
set in the title
field of the schema or the collection name if no title
is specified.
type Movie { _id: ObjectId title: String! year: Int rated: String runtime: Int director: String cast: [String] }
Field Mapping
App Services attempts to map fields in your collection schema directly to fields in your GraphQL types. The definition of valid names described in the GraphQL spec does not support all possible valid document field names, so App Services applies the following transformation rules to determine field names in generated GraphQL types:
strip unsupported characters
strip leading numbers
convert to camel case
omit fields that begin with a double underscore (e.g.
__myField
)
BSON Type Mapping
The GraphQL type system is similar but not identical to the BSON types that you can use in a schema. App Services automatically attempts to map between the BSON types in your schema and supported GraphQL types. If a field type does not have a GraphQL equivalent, App Services does not include the field in the generated GraphQL document type.
The following table lists BSON types that you can use in a schema and the GraphQL types that they map to:
JSON/BSON Type | GraphQL Type |
---|---|
objectId | ObjectId |
int | Int |
long | Int |
double | Float |
decimal | Float |
date | DateTime |
timestamp | DateTime |
Note
JSON supports two types that represent "no value": undefined
and
null
. The GraphQL spec supports null
but not undefined
,
so your app converts undefined
values in the following way:
If a document field is explicitly set to
undefined
then the corresponding GraphQL type is an empty object, i.e.{}
.If the field name is not defined for the document at all, or if the value is explicitly set to
null
, then the corresponding GraphQL type isnull
.
Input Types
GraphQL uses input types to represent parameters that you pass to queries and mutations. This is a standard approach used by all GraphQL APIs to define unambiguous, type-safe user inputs.
QueryInput
A QueryInput
object defines a set of one or more conditions that a document
must meet in order to be included in a query. The object may include fields from
the document type as well as any of the operator fields that App Services
automatically generates based on each field's type.
Document Fields: If a
QueryInput
field has the same name as a field in the document type, then App Services matches a document if the value specified in the input field and the value of the field in the document are the same.Example
The following query includes a
QueryInput
with two fields,rated
andyear
. Both of these field names are defined in theMovie
document type, so App Services performs an equality match for both.The query returns the title of all movies released in the year 2000 that are rated R.
movies(query: { rated: "R", year: 2000 }) { title } Operator Fields: If a
QueryInput
field is a valid operator field for the queried type, then App Services matches a document if the operator evaluates totrue
.Example
The following query includes a
QueryInput
with two fields,rated_in
andyear_gt
. Both of these are operator fields, so App Services evaluates each operator to determine if a document matches.The query returns the title of all movies released after the year 2000 that are rated either G or PG-13.
movies(query: { rated_in: ["G", "PG-13"], year_gt: 2000 }) { title }
Comparison Operator Fields
A comparison operator field allows you to define a condition that is more complex than exact equality, such as a range query. App Services generates a set of comparison operator fields for every field in the document type based on the field type. Each comparison operator typically applies to only a subset of all field types, so App Services only generates operator fields for valid combinations.
A comparison operator field evaluates to true
for a given document if the
value of the field in the document satisfies the operator condition relative to
the specified value.
Comparison operator fields have the following form:
<Field Name>_<Operator>: <Operator Value>
Operator | Supported Field Types | Operator Value Type | Description | ||||
---|---|---|---|---|---|---|---|
gt | Int Float String ObjectId DateTime | <Field Type> | Finds documents where the field is greater than the specified value. ExampleThis query finds all movies that were released after the year 2000:
| ||||
gte | Int Float String ObjectId DateTime | <Field Type> | Finds documents where the field is greater than or equal to the specified value. ExampleThis query finds all movies that were released in or after the year 2000:
| ||||
lt | Int Float String ObjectId DateTime | <Field Type> | Finds documents where the field is less than the specified value. ExampleThis query finds all movies that were released before the year 2000:
| ||||
lte | Int Float String ObjectId DateTime | <Field Type> | Finds documents where the field is less than or equal to the specified value. ExampleThis query finds all movies that were released in or before the year 2000:
| ||||
ne | Int Float String Boolean ObjectId DateTime | <Field Type> | Finds documents where the field is not equal to the specified value. ExampleThis query finds all movies that were released in any year other than 2000:
| ||||
in | Int Float String Boolean ObjectId DateTime Array | [<Field Type>] | Finds documents where the field is equal to any value in the specified
array. If the field is an ExampleThis query finds all movies that feature either or both of Emma Stone and Ryan Gosling:
| ||||
nin | Int Float String Boolean ObjectId DateTime Array | [<Field Type>] | Finds documents where the field is not equal to any value in the
specified array. If the field is an ExampleThis query finds all movies that are not rated either G or PG-13:
|
Logical Operator Fields
A logical operator field allows you to define logical combinations of
independent QueryInput
objects. App Services generates root-level logical operator
fields for all QueryInput
types.
A logical operator field evaluates to true
for a given document if the
evaluated result of all specified QueryInput
objects satisfy the operator
condition.
Logical operator fields have the following form:
<Operator>: [<QueryInput>, ...]
Operator | Operator Value Type | Description | ||||||
---|---|---|---|---|---|---|---|---|
AND | [QueryInput!] | Finds documents that match all of the provided ExampleThis query finds all movies that are rated PG-13 and have a runtime of less than 120 minutes:
| ||||||
OR | [QueryInput!] | Finds documents that match any of the provided ExampleThis query finds all movies that are rated either G or PG-13:
|
Element Operator Fields
An element operator field allows you to define a boolean condition that describes a field in the document. App Services generates a set of element operator fields for every field in the document type.
An element operator field evaluates to true
for a given document if the
result of evaluating the operator condition on the field in the document matches
the specified boolean value.
Element operator fields have the following form:
<Field Name>_<Operator>: <Operator Value>
Operator | Supported Types | Operator Value Type | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
exists | Available for all types | Boolean | Finds documents where the field is not ExampleThis query finds all movies that do not have a value defined for the
|
InsertInput
An InsertInput
object defines a document to insert into a collection. The
document must conform to the GraphQL document type and include all required
fields.
Example
The following mutation includes an InsertInput
with several fields that
are all defined in the Movie
document type. The Movie
type requires
all documents to have a title
field, so the InsertInput
must include
one.
The mutation inserts a new movie named "My Fake Film".
insertOneMovie(input: { title: "My Fake Film", rated: "UNRATED", year: 2020 }) { title }
UpdateInput
An UpdateInput
object defines a new value for one or more fields in a
document. The updated document includes the new field values. Any fields that
you do not specify remain unchanged. The updated values must conform to the
GraphQL document type.
Example
The following mutation includes an UpdateInput
that sets the title
field to "My Super Real Film".
updateOneMovie( query: { title: "My Fake Film" } set: { title: "My Super Real Film" } ) { title }
RelationInput
A RelationInput
defines a new set of related documents for a relationship
field in the mutated document. You can reference documents that already exist in
the related collection with the link
field or insert new documents into the
related collection with the create
field.
You cannot use both link
and create
at the same time. If both
are specified, the create
operation takes precedence and the
link
is ignored.
type RelationInput { link: [ObjectId] create: [InsertInput] }
Example
The following mutation includes an UpdateInput
that modifies the
reviews
field. The field contains an array of _id
values for
documents in a separate reviews
collection for to the field has a defined
relationship.
The mutation sets the relationship to point to one newly created document and
two existing documents in the reviews
collection.
updateOneMovie( query: { title: "My Fake Film" } set: { reviews: { link: ["", ""] create: [] } } ) { title }
SortByInput
A SortByInput
enum defines a sort order for documents returned by a query.
You can sort in ascending and descending order by any root-level field that does
not have a type of object
or array
. The GraphQL API does not support
nested sorts.
App Services generates two sort enum values for each field. Each value is a
fully-capitalized identifier that combines the field name and the sort
direction, either ASC
or DESC
.
Example
The following query returns movies sorted by the year they were released with the most recent movies listed first.
movies(sortBy: YEAR_DESC) { title }
Query Resolvers
App Services generates two GraphQL queries for each collection:
A singular query that finds a specific document in the collection.
A plural query that finds all documents in the collection. You can filter a plural query to include only the subset of documents in a collection that match a
QueryInput
.
Find a Single Document
The single document query field uses the same name as the data type that the collection contains. It returns a single document of the queried type and accepts the following parameters:
Parameter | Type | Description |
---|---|---|
query | Optional. An object that defines a filter for documents in the collection. The object may specify one or more fields from the data type and must include a value for each field. The query matches all documents that include the specified field values. If you do not specify a |
query { movie(query: { title: "The Matrix" }) { title year runtime director } }
Find Multiple Documents
The multiple document query field uses the same name as the data type
that the collection contains but has an additional "s"
appended to
the type name. It returns an array of documents of the queried type and
accepts the following parameters:
Parameter | GraphQL Type | Description |
---|---|---|
query | Optional. An object that defines a filter for documents in the collection. The object may specify one or more fields from the data type and must include a value for each field. The query matches all documents that include the specified field values. If you do not specify a | |
limit | Int | Optional. Default 100 . The maximum number of documents to
include in the query result set. If the query matches more than
the set limit then it only returns a subset of matched documents. |
sortBy | Optional. A value that defines a sort order for documents in the
query result set. You can sort in ascending and descending order
by any root-level field that does not have a type of The
If you do not specify a |
query { movies( query: { year: 2000 } limit: 100 sortBy: TITLE_ASC ) { title year runtime director } }
Mutation Resolvers
App Services generates a set of mutations for the documents in each collection. These allow you insert, modify, and delete one or more documents.
Insert a Single Document
The single document insert mutation field uses the name
insertOne<Type>
where <Type>
is the singular name of the data
type that the collection contains. It returns the inserted document and
accepts the following parameters:
Parameter | Type | Description |
---|---|---|
data | Required. A document to insert into the collection. If the
collection schema marks a field as required then this document
must include a valid value for that field. App Services automatically
converts GraphQL types in the InsertInput object into their
respective BSON type. |
mutation { insertOneMovie(data: { title: "Little Women" director: "Greta Gerwig" year: 2019 runtime: 135 }) { _id title } }
Insert Multiple Documents
The multiple document insert mutation field uses the name
insertMany<Type>s
where <Type>
is the singular name of the data
type that the collection contains. It returns the inserted document and
accepts the following parameters:
Parameter | Type | Description |
---|---|---|
data | [InsertInput!]! | Required. An array of documents to insert into the collection.
The array must contain at least one document. If the collection
schema marks a field as required then each document must include
a valid value for that field. App Services automatically converts
GraphQL types in the InsertInput object into their respective
BSON type as defined in the collection schema. |
mutation { insertManyMovies(data: [ { title: "Little Women" director: "Greta Gerwig" year: 2019 runtime: 135 }, { title: "1917" director: "Sam Mendes" year: 2019 runtime: 119 } ]) { _id title } }
Update a Single Document
The single document update mutation field uses the name
updateOne<Type>
where <Type>
is the singular name of the data
type that the collection contains. It returns the updated document and
accepts the following parameters:
Parameter | Type | Description |
---|---|---|
query | Optional. An object that configures which documents in the collection to update. The object may specify one or more fields from the data type and must include a value for each field. The query matches all documents that include the specified field values. If you do not specify a | |
set | UpdateInput! | Required. An object that defines a new value for one or more
fields in the document. The updated document will include the new
field values. Any fields that you do not specify remain
unchanged. App Services automatically converts GraphQL types in the
UpdateInput object into their respective BSON type. |
mutation { updateOneMovie( query: { title: "The Room" } set: { runtime: 99 } ) { _id title } }
Update Multiple Documents
The multiple document update mutation field uses the name
updateMany<Type>s
where <Type>
is the singular name of the data
type that the collection contains. It returns an UpdateManyPayload
document that describes the number of fields that were matched and
modified and accepts the following parameters:
Parameter | Type | Description |
---|---|---|
query | Optional. An object that configures which documents in the collection to update. The object may specify one or more fields from the data type and must include a value for each field. The query matches all documents that include the specified field values. If you do not specify a | |
set | Required. An object that defines a new value for one or more
fields in the document. The updated document will include the new
field values. Any fields that you do not specify remain
unchanged. App Services automatically converts GraphQL types in the
UpdateInput object into their respective BSON type. |
mutation { updateManyMovies( query: { director: "Tommy Wiseau" } set: { director: "Tom Wiseau" } ) { matchedCount modifiedCount } }
Upsert a Single Document
The single document upsert mutation field uses the name
upsertOne<Type>
where <Type>
is the singular name of the data
type that the collection contains. This resolver updates a document that
matches the query parameter and inserts a new document if none match the
query. It returns the upserted document and accepts the following
parameters:
Parameter | Type | Description |
---|---|---|
query | Optional. An object that configures which document to update. The object may specify one or more fields from the data type and must include a value for each field. The query matches all documents that include the specified field values. If you do not specify a | |
data | Required. The document to insert if the query does not match
any existing documents. If the query does match a document
replaces the queried document. If the collection schema marks a
field as required then this document must include a valid value
for that field. App Services automatically converts GraphQL types in
the InsertInput object into their respective BSON type. |
mutation { upsertOneMovie( query: { title: "Blacksmith Scene" } data: { title: "Sandcastles in the Sand", director: "Robin Scherbatsky" runtime: 90 year: 2002 } ) { _id title } }
Replace a Single Document
The single document replacement mutation field uses the name
replaceOne<Type>
where <Type>
is the singular name of the data
type that the collection contains. It returns the replaced document and
accepts the following parameters:
Parameter | Type | Description |
---|---|---|
query | Optional. An object that configures which documents in the collection to replace. The object may specify one or more fields from the data type and must include a value for each field. The query matches all documents that include the specified field values. If you do not specify a | |
data | Required. The document that replaces the queried document. If the
collection schema marks a field as required then this document
must include a valid value for that field. App Services automatically
converts GraphQL types in the InsertInput object into their
respective BSON type. |
mutation { replaceOneMovie( query: { title: "Blacksmith Scene" } data: { title: "Sandcastles in the Sand", director: "Robin Scherbatsky" runtime: 90 year: 2002 } ) { _id title } }
Delete a Single Document
The single document delete mutation field uses the name
deleteOne<Type>
where <Type>
is the singular name of the data
type that the collection contains. It returns the deleted document and
accepts the following parameters:
Parameter | Type | Description |
---|---|---|
query | Required. An object that configures which document in the collection to delete. The object may specify one or more fields from the data type and must include a value for each field. The query matches all documents that include the specified field values. If the |
mutation { deleteOneMovie(query: { title: "The Room" }) { _id title year runtime director } }
Delete Multiple Documents
The multiple document delete mutation field uses the name
deleteMany<Type>s
where <Type>
is the singular name of the data
type that the collection contains. It returns a DeleteManyPayload
document that describes the number of documents that were deleted and
accepts the following parameters:
Parameter | Type | Description |
---|---|---|
query | Optional. An object that configures which documents in the collection to delete. The object may specify one or more fields from the data type and must include a value for each field. The query matches all documents that include the specified field values. If you do not specify a |
mutation { deleteManyMovies(query: { director: "Tommy Wiseau" }) { deletedCount } }
Paginate Data
You can paginate data in your queries with the types provided by the GraphQL API's generated schema.
The Atlas GraphQL API does not have an offset
operator, like the
GraphQL documentation recommends for pagination.
Instead you can use the generated schema's find multiple documents query resolvers
with query
, limit
, and sortBy
operators to paginate data.
To paginate data in ascending order:
query PaginateAscending( # Do not include `previousTitle` for the first query # in a pagination sequence. $previousTitle: String, $limit: Int!, ) { movies( query: { title_gt: $previousTitle } limit: $limit sortBy: TITLE_ASC ) { title year runtime director } }
To paginate data in descending order:
query PaginateAscending( # Do not include `nextTitle` for the first query # in a pagination sequence. $nextTitle: String, $limit: Int!, ) { movies( query: { title_lt: $nextTitle } limit: $limit sortBy: TITLE_DESC ) { title year runtime director } }
For a example of this pagination pattern implemented in a client application, refer to Paginate Data in the Realm Web SDK documentation.
Note
This approach to pagination is similar to range queries for MongoDB drivers, as described in the MongoDB Server documentation.