How to use the API

Overview

This section aims to provide the working details of the GraphQL API that can be used to query your Realm Object Server. It is important to note that you will need to properly authenticate a user before consuming data with the API.

Endpoints

The GraphQL endpoint is mounted on /graphql/:path where path is the relative path of the Realm.

The GraphQL subscription endpoint is ws://ROS-URL:ROS-PORT/graphql/:path.

The GraphQL schema endpoint is /graphql/schema/:path where path is the relative path of the Realm.

The GraphiQL Explorer (visual exploratory tool) endpoint is mounted on /graphql/explore/:path where path, again, is the path of the Realm.

Authentication

By default, all endpoints and actions are authenticated.

If you wish to disable authentication while developing, you can pass disableAuthentication: true to the service constructor. This is only possible if self-hosting the server and is meant strictly for usage during development.

Obtaining an Access Token

Authentication is done with an Access Token, obtained by executing POST request against the /auth endpoint:

First, you'll need to login the user with their provider. For example, when authenticating with username/password, pass the following payload:

{
"app_id":"",
"provider":"password",
"data":"MY-USERNAME",
"user_info": {
"register":false,
"password":"MY-PASSWORD"
}
}

The response will look something like:

{
"refresh_token": {
"token":"VERY-LONG-TOKEN-HERE"
}
}

We'll need the refresh token to obtain the access token by posting again to /auth:

{
"app_id":"",
"provider":"realm", // Note provider is 'realm'
"data":"REFRESH_TOKEN.TOKEN", // Token from previous response
"path":"REALM-PATH" // Path of the realm you want to access, e.g. '/user-id/tickets
}

The response will now contain:

{
"access_token": {
"token":"VERY-LONG-TOKEN-HERE"
},
"token_data": {
"expires": 1512402618 // unix timestamp
}
}

We'll need this access token to perform all graphql actions. This token must be refreshed before it expires using the refresh token obtained earlier to avoid getting 401: Unauthorized responses.

Queries

Queries are regular GET/POST requests and require standard authorization headers.

Authorization: ACCESS_TOKEN.TOKEN

To query, you start with a query node. The schema of the Realm file is automatically used to generate the GraphQL schema that exposes the following operations:

  • Query for all objects of a certain type: all object types have a pluralized node, e.g. users, accounts, etc. It accepts the following optional arguments:

    • query: a verbatim realm.js query that will be used to filter the returned dataset.

    • sortBy: a property on the object to sort by.

    • descending: sorting direction (default is false, i.e. ascending).

    • skip: offset to start taking objects from.

    • take: maximum number of items to return.

  • Query for object by primary key: object types that have a primary key defined will have a singularized node, e.g. user, realmFile, etc. It accepts a single argument that is the primary key of the object.

  • Inverse relationships: all models expose a function called _linkingObjects that allows you to query for objects that link to the current one. Since GraphQL doesn't have true generic support, the return type is a union so you'll need to switch on the target object type. Depending on the value of includeCountInResponses in the service config, the return type on which you need to switch is either *TargetType*Collection or *TargetType*:

Example inverse relationship query
query {
users {
name
birthday
dogs:_linkingObjects(objectType:"Dog" property: "owner") {
...on Dog {
name
breed
}
}
}
}

For models which already have a plural name definition in your schema, you will need to add another "s" to your query. (i.e. "cars" becomes "carss", "data" becomes "datas", etc)

For more information on how to use query see the GraphQL documentation.

Mutations

Mutations are regular GET/POST requests and require standard authorization headers.

Realm automatically generates acreate<ObjectType>and adelete<ObjectType> mutation for each object type in a realm. For example, a Realm that contains User and Account object has createUser, deleteUser, createAccount and deleteAccount mutations. You can use the automatically generated mutations to create, update, and delete objects in a realm.

For information on how to write and use a mutation, refer to the official GraphQL documentation.

Add an Object

To add an object to a realm, use the create<ObjectType> mutation for the object type and specify the object in the input parameter with the appropriate<ObjectType>Inputinput type.

mutation CreateNewUser($user: UserInput!) {
createUser(input: $user) {
name
}
}

To add multiple instances of an object type, use the create<ObjectType>s mutation for the object type and specify the objects in the input parameter as an array of the appropriate <ObjectType>Input input type.

mutation CreateNewUsers($users: [UserInput]!) {
createUsers(input: $users) {
name
}
}

Realm automatically adds any related objects that you include in the input, e.g. if you specify threeaccounts in the addUserinput, Realm will also add the account objects.

Update an Object

To update an object, use the create<ObjectType> mutation for the object type with a value set for the updatePolicy parameter. Specify the object in the input parameter with the appropriate<ObjectType>Inputinput type.

mutation UpdateExistingUser($user: UserInput!) {
createUser(input: $user, updatePolicy: MODIFIED) {
name
}
}

To update multiple instances of an object type, use the create<ObjectType>s mutation for the object type with a value set for the updatePolicy parameter. Specify the objects in the input parameter as an array of the appropriate <ObjectType>Input input type.

mutation UpdateExistingUsers($users: [UserInput]!) {
createUsers(input: $users, updatePolicy: MODIFIED) {
name
}
}

The value of updatePolicy determines how Realm handles the update operation. You may choose any of the following update policies:

Policy

Description

NONE

Creates the object if no existing object has the same primary key, or throws an error otherwise.

MODIFIED

Updates only those properties that are different between the input and the specified object.

ALL

Realm should fully replace the specified object with the provided input.

Delete an Object

If an object type has a primary key, use the delete<ObjectType> mutation for the object type and specify the object's primary key value in the id parameter. The mutation returns true if the object was deleted, and false if no existing object has the specified primary key.

mutation DeleteUser($userId: String!) {
deleteUser(id: $userId)
}

To delete one or more objects of an object type, use the delete<ObjectType>s mutation for the object type and specify a realm-js query in the query parameter. The mutation deletes all objects that match the specified query. If you omit the query parameter, then the mutation deletes all objects of the specified type. The mutation returns the number of objects that were deleted.

mutation DeleteUsers($query: String!) {
deleteUsers(query: $query)
}

Use DELETE /graphql/schema/:path to clear the cached schema of the Realm at path if schema caching is enabled (e.g. due to a recent schema change).

Subscription

Subscriptions use websocket connections, which require authentication after the connection is established before any GraphQL-related message can be sent.

Before sending any graphql-related messages, you'll need to send an object message, containing an authToken field set to the access token:

{
token: ACCESS_TOKEN.TOKEN
}

To subscribe for change notifications, start with a subscription node. The schema of the Realm file is automatically used to generate the GraphQL schema that exposes the following operations:

  • Subscribing for queries: all object types have a pluralized node, e.g. users, accounts, etc. Every time an item is added, deleted, or modified in the dataset, the updated state will be pushed via the subscription socket. The node accepts the following optional arguments:

    • query: a verbatim realm.js query that will be used to filter the returned dataset.

    • sortBy: a property on the object to sort by.

    • descending: sorting direction (default is false, i.e. ascending).

    • skip: offset to start taking objects from.

    • take: maximum number of items to return.

IMPORTANT NOTE ON TOKEN VALIDATION: The access token for subscriptions is validated only when the socket connection is established and not when emitting notifications by the server. This means that it's the client's responsibility to terminate the connection if the user logs out or loses access to the Realm.