Developer

GraphQL subscriptions

GraphQL Subscriptions enable clients to listen to real-time messages whenever important changes happen inside of Bluescape workspaces and organizations. The client connects to the server with a bi-directional communication channel using the WebSocket protocol and sends a subscription query that specifies which event it is interested in. When an event is triggered, the Bluescape server executes the stored GraphQL query, and the result is sent back to the client using the same communication channel.

The client can unsubscribe by sending a message to the Bluescape server. The Bluescape server can also unsubscribe at any time due to errors or timeouts.

List of Subscriptions

You can access the playground via the page: click the Docs link on the far right border, and look for the list of currently available subscriptions in the SUBSCRIPTIONS section at the bottom of the column.

Example of implementation

Below you can find 2 types of implementations: using the GraphQl Playground to test and inspect the subscriptions, and using a script to capture an process the subscription events.

Subscription implementation in GraphQL Playground

You can access the playground via the page. Here is an example of subscription for events, for reporting the change in position (x,y) of Image elements, using the commands subscription:

subscription imageElementUpdated($workspaceId: String!) {
  commands(workspaceId: $workspaceId) {
    ... on UpdateElementCommand {
      workspaceId
      id
      data {
        ... on UpdateImage {
          transform {
            x
            y
          }
        }
      }
    }
  }
}

Set the correct values for:

  • QUERY VARIABLES:
    {
        "workspaceId": "<workspaceId>"
    }
    
  • and HTTP HEADERS
    {
      "Authorization":"Bearer <SET_TOKEN>"
    }
    

Click the "Play" button in the top middle section of the screen. You should see a "Listening..." message at the bottom of the right panel in the Playground. Please interact with an image in the workspace: change its position.
After moving the image, you will see that a new event is reported to the subscription, where the position (x,y) has changed:

Subscription implementation in a script

The implementation in the GraphQL Playground shows us how the data for the subscription will be delivered. The next step is to use a script or an implementation to take specific actions based on the data of the events that we are receiving from the subscription.
Please inspect the examples below to implement a basic parser for the subscription events.

/*
Requires the following libraries and versions:
1) ws, version 7.4.5
2) graphql-ws, version 4.5.1

To install them, run:
npm install <library-name>
*/
var ws = require('ws');
var {createClient} = require('graphql-ws');
const JWT_TOKEN = '';
// Please note the 'wss' protocol
const WS_URL = 'wss://';

const observer = {
  error(e) {
    console.log('Observer.error', e);
  },
  next(eventData) {
    console.log('Observer.next');
    console.dir(eventData, {depth: null});
    // Here you can inspect and process the incoming eventData to take specific actions 
  },
  complete() {
    console.log('Observer.complete');
  }
}
function subscribe(query, variables) {
  const client = createClient({
    url: WS_URL,
    webSocketImpl: ws,
    connectionParams: () => {
      return {
        Authorization: `Bearer ${JWT_TOKEN}`
      }
    },
  });
  client.subscribe({query, variables}, observer);
}

// Set the subscription
subscribe(`subscription imageChangesSubscription($workspaceId: String!) {
    commands(workspaceId: $workspaceId) {
      ... on UpdateElementCommand {
        workspaceId
        id
        data {
          ... on UpdateImage {
            transform {
              x
              y
            }
          }
        }
      }
    }
  }`, {
    workspaceId: '<workspaceId>'
  });

When you move an image, this is the type of event you will receive:

 Update received:
{
  data: {
    commands: {
      workspaceId: '<workspaceId>',
      id: '609abX787e69f2ca25b65262',
      data: { transform: { x: 13599.666666666668, y: -8254.500000000004 } }
    }
  }
}
 
You can parse this even data and trigger an action.