How to use the API

Last updated 4 days ago

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.

Query

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.

Mutation

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

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

  • Add object: all object types have an addObjectType node, e.g. addUser, addAccount, etc. It accepts a single argument that is the object to add. Related objects will be added as well, e.g. specifying accounts in the addUser input will add the account objects.

  • Add or update object: objects with primary key defined have an updateObjectType node, e.g. updateUser, updateRealmFile. It accepts a single argument that is the object to update. Partial updates are also allowed as long as the primary key value is specified.

  • Differentially update an object: objects with primary key defined have an diffUpdateObjectTypenode, e.g. diffUpdateUser, diffUpdateRealmFile. It accepts a single argument that is the object to update. Partial updates are also allowed as long as the primary key value is specified. Updating related objects only works if those related objects also have a primary key defined. This method is preferred when possible as it will generate the least historical footprint on the server.

  • Delete objects:

    • Objects with primary key defined have a deleteObjectType node, e.g. deleteUser, deleteRealmFile. It accepts a single argument that is the primary key of the object to delete. Returns true if object was deleted, false otherwise.

    • All object types have a deleteObjectTypes node, e.g. deleteUsers, deleteAccounts, etc. It accepts a single optional argument - query that will be used to filter objects to be deleted. If not supplied, all objects of this type will be deleted.

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).

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

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.