GraphcoolDocs
FAQ

Subscriptions

Last updated a day ago Edit this page

Use subscriptions to receive data updates in realtime. Subscriptions in the GraphQL schema are derived from types and relations.

#Overview

GraphQL subscriptions allow you to be notified in realtime of changes to your data. This is an example subscription that notifies you whenever a new Post node is created:

Query Variables
Hit the Play Button to get a response here
Docs

Subscriptions use a special websocket endpoint.

Here's a list of available subscriptions. To explore them, use the playground inside your service.

You can combine multiple subscription triggers into a single subscription query to control exactly what events you want to be notified of.

#Subscription requests

When using Apollo Client, you can use subscription-transport-ws to combine it with a WebSocket client. Here's an example.

You can also use the GraphQL Playground or any WebSocket client as described below.

#Playground

A GraphQL Playground can be used to explore and run GraphQL subscriptions.

Before diving into a specific implementation, it's often better to get familiar with the available operations in the playground first.

#Plain WebSockets

Establish connection

Subscriptions are managed through WebSockets. First establish a WebSocket connection and specify the graphql-subscriptions protocol:

1
let webSocket = new WebSocket('wss://subscriptions.graph.cool/v1/__SERVICE_ID__', 'graphql-subscriptions');

Initiate handshake

Next you need to initiate a handshake with the WebSocket server. You do this by listening to the open event and then sending a JSON message to the server with the type property set to init:

1
2
3
4
5
6
7
webSocket.onopen = (event) => {
  const message = {
      type: 'init'
  }

  webSocket.send(JSON.stringify(message))
}

React to messages

The server may respond with a variety of messages distinguished by their type property. You can react to each message as appropriate for your application:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
webSocket.onmessage = (event) => {
  const data = JSON.parse(event.data)

  switch (data.type) {
    case 'init_success': {
      console.log('init_success, the handshake is complete')
      break
    }
    case 'init_fail': {
      throw {
        message: 'init_fail returned from WebSocket server',
        data
      }
    }
    case 'subscription_data': {
      console.log('subscription data has been received', data)
      break
    }
    case 'subscription_success': {
      console.log('subscription_success')
      break
    }
    case 'subscription_fail': {
      throw {
        message: 'subscription_fail returned from WebSocket server',
        data
      }
    }
  }
}

Subscribe to data changes

To subscribe to data changes, send a message with the type property set to subscription_start:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const message = {
  id: '1',
  type: 'subscription_start',
  query: `
    subscription newPosts {
      Post(filter: {
        mutation_in: [CREATED]
      }) {
        mutation
        node {
          description
          imageUrl
        }
      }
    }
  `
}

webSocket.send(JSON.stringify(message))

You should receive a message with type set to subscription_success. When data changes occur, you will receive messages with type set to subscription_data. The id property that you supply in the subscription_start message will appear on all subscription_data messages, allowing you to multiplex your WebSocket connection.

Unsubscribe from data changes

To unsubscribe from data changes, send a message with the type property set to subscription_end:

1
2
3
4
5
6
const message = {
  id: '1',
  type: 'subscription_end'
}

webSocket.send(JSON.stringify(message))

#Type subscriptions

For every available model type mutation in your data model, certain subscriptions are automatically generated.

For example, if your schema contains a Post type:

1
2
3
4
5
type Post @model {
  id: ID! @isUnique
  title: String!
  description: String
}

a Post subscription is available that you can use to be notified whenever certain nodes are created, updated or deleted.

#Subscribing to created nodes

For a given type, you can subscribe to all nodes that are being created using the generated type subscription.

Subscribe to all created nodes

If you want to subscribe to created nodes of the Post type, you can use the Post subscription and specify the filter object and set mutation_in: [CREATED].

Query Variables
Hit the Play Button to get a response here
Docs

The payload contains

  • mutation: in this case it will return CREATED
  • node: allows you to query information on the created node and connected nodes

Subscribe to specific created nodes

You can make use of a similar filter system as for queries using the node argument of the filter object.

For example, to only be notified of a created post if a specific user follows the author:

Query Variables
Hit the Play Button to get a response here
Docs

#Subscribing to deleted nodes

For a given type, you can subscribe to all nodes that are being deleted using the generated type subscription.

Subscribe to all deleted nodes

If you want to subscribe for updated nodes of the Post type, you can use the Post subscription and specify the filter object and set mutation_in: [DELETED].

1
2
3
4
5
6
7
8
9
10
11
12
subscription deletePost {
  Post(
    filter: {
      mutation_in: [DELETED]
    }
  ) {
    mutation
    previousValues {
      id
    }
  }
}

The payload contains

  • mutation: in this case it will return DELETED
  • previousValues: previous scalar values of the node

Note: previousValues is null for CREATED subscriptions.

Subscribe to specific deleted nodes

You can make use of a similar filter system as for queries using the node argument of the filter object.

For example, to only be notified of a deleted post if a specific user follows the author:

Query Variables
Hit the Play Button to get a response here
Docs

#Subscribing to updated nodes

For a given type, you can subscribe to all nodes being updated using the generated type subscription.

Subscribe to all updated nodes

If you want to subscribe to updated nodes of the Post type, you can use the Post subscription and specify the filter object and set mutation_in: [UPDATED].

Query Variables
Hit the Play Button to get a response here
Docs

The payload contains

  • mutation: in this case it will return UPDATED
  • node: allows you to query information on the updated node and connected nodes
  • updatedFields: a list of the fields that changed
  • previousValues: previous scalar values of the node

Note: updatedFields is null for CREATED and DELETED subscriptions. previousValues is null for CREATED subscriptions.

Subscribe to updated fields

You can make use of a similar filter system as for queries using the node argument of the filter object.

For example, to only be notified of an updated post if its description changed:

Query Variables
Hit the Play Button to get a response here
Docs

Similarily to updatedFields_contains, more filter conditions exist:

  • updatedFields_contains_every: [String!]: matches if all fields specified have been updated
  • updatedFields_contains_some: [String!]: matches if some of the specified fields have been updated

Note: you cannot use the updatedFields filter conditions together with mutation_in: [CREATED] or mutation_in: [DELETED]!

#Relation subscriptions

Currently, subscriptions for relation updates are only available with a workaround using update subscriptions.

#Subscribing to relation changes

You can force a notification changes by touching nodes. Add a dummy: String field to the type in question and update this field for the node whose relation status just changed.

1
2
3
4
5
6
mutation updatePost {
  updatePost(
    id: "some-id"
    dummy: "dummy" # do a dummy change to trigger update subscription
  )
}

If you're interested in a direct relation trigger for subscriptions, please join the discussion on GitHub.

#Combining subscriptions

You can subscribe to multiple mutations on the same type in one subscription.

#Subscribe to all changes to all nodes

Using the mutation_in argument of the filter object, you can select the type of mutation that you want to subscribe to. For example, to subscribe to the createPost, updatePost and deletePost mutations:

Query Variables
Hit the Play Button to get a response here
Docs

#Subscribe to all changes to specific nodes

To select specific nodes that you want to be notified about, use the node argument of the filter object. You can combine it with mutation_in. For example, to only be notified of created, updated and deleted posts if a specific user follows the author:

Query Variables
Hit the Play Button to get a response here
Docs

Note: previousValues is null for CREATED subscriptions and updatedFields is null for CREATED and DELETED subscriptions.

#Advanced subscription filters

You can make use of a similar filter system as for queries using the filter argument.

For example, you can subscribe to all CREATED and DELETE subscriptions, as well as all UPDATED subscriptions when the imageUrl was updated

Query Variables
Hit the Play Button to get a response here
Docs

Note: Using any of the updatedFields filter conditions together with CREATED or DELETED subscriptions results in an error. previousValues is null for CREATED subscriptions and updatedFields is null for CREATED and DELETED subscriptions.

Was this page helpful?