Subscriptions
RAM usage of subscriptions scales poorly under high load, making the feature unsuitable for most production uses. There are currently no plans to fix this issue.
OpenReader supports GraphQL subscriptions via live queries. To use these, a client opens a websocket connection to the server and sends a subscription query there. The query body is then repeatedly executed (every 5 seconds by default) and the results are sent to the client whenever they change.
To enable subscriptions, add the additional --subscriptions flag to the squid-graphql-server startup command. The poll interval is configured with the --subscription-poll-interval flag. For details and a full list of available options, run
npx squid-graphql-server --help
For each entity types, the following queries are supported for subscriptions:
${EntityName}ById-- query a single entity${EntityName}s-- query multiple entities with awherefilter Note that despite being deprecated from the regular query set,${EntityName}squeries will continue to be available for subscriptions going forward.
Local runs
To enable subscriptions, add the --subscriptions flag to serve and serve:prod commands at commands.json:
...
"serve": {
"description": "Start the GraphQL API server",
"cmd": ["squid-graphql-server", "--subscriptions"]
},
"serve:prod": {
"description": "Start the GraphQL API server in prod",
"cmd": ["squid-graphql-server", "--subscriptions", "--dumb-cache", "in-memory"]
},
...
A ws endpoint will be available the usual localhost:<GQL_PORT>/graphql URL.
Subsquid Cloud deployments
For Subsquid Cloud deployments, make sure to use the updated serve:prod command in the deployment manifest:
# ...
deploy:
# other services ...
api:
cmd: [ "sqd", "serve:prod" ]
The subscription wss endpoint will be available at the canonical API endpoint wss://{org}.subsquid.io/{name}/v/v{version}/graphql.
Example
Let's take the following simple schema with account and transfer entities:
type Account @entity {
"Account address"
id: ID!
transfersTo: [Transfer!] @derivedFrom(field: "to")
transfersFrom: [Transfer!] @derivedFrom(field: "from")
}
type Transfer @entity {
id: ID!
timestamp: DateTime! @index
from: Account!
to: Account!
amount: BigInt! @index
}
After modifying commands.json start the GraphQL server with subscriptions with
npx squid-graphql-server
The following sample script will subscribe to the most recent transfers (by timestamp).
const WebSocket = require('ws')
const { createClient } = require('graphql-ws');
const port = process.env.GQL_PORT || 4350
const host = process.env.GQL_HOST || 'localhost'
const proto = process.env.GQL_PROTO || 'ws'
const client = createClient({
webSocketImpl: WebSocket,
url: `${proto}://${host}:${port}/graphql`,
});
client.subscribe(
{
query: `
subscription {
transfers(limit: 5, orderBy: timestamp_DESC) {
amount
blockNumber
from {
id
}
to {
id
}
}
}
`,
},
{
next: (data) => {
console.log(`New transfers: ${JSON.stringify(data)}`);
},
error: (error) => {
console.error('error', error);
},
complete: () => {
console.log('done!');
},
}
);