Subscriptions
Subscriptions allow clients to listen to real-time messages from the server. In GraphQL, it’s straightforward to enable subscriptions on any type.
We’re overhauling Dgraph’s docs to make them clearer and more approachable. If you notice any issues during this transition or have suggestions, please let us know.
Subscriptions allow clients to listen to real-time messages from the server. 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’s interested in. When an event is triggered, the 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 server. The server can also unsubscribe at any time due to errors or timeouts. A significant difference between queries or mutations and subscriptions is that subscriptions are stateful and require maintaining the GraphQL document, variables, and context over the lifetime of the subscription.
Enable subscriptions in GraphQL
In GraphQL, it’s straightforward to enable subscriptions on any type. You can
add the @withSubscription
directive to the schema as part of the type
definition, as in the following example:
@withSubscription
with @auth
You can use @auth access control rules
in conjunction with @withSubscription
.
Consider following Schema that has both the @withSubscription
and @auth
directives defined on type Todo
.
The generated GraphQL API expects a JWT token in the X-Dgraph-AuthToken
header
and uses the USER
claim to apply a Role-based Access Control (RBAC). The
authorization rule enforces that only to-do tasks owned by $USER
are returned.
WebSocket client
Dgraph uses the WebSocket protocol subscription-transport-ws
.
Clients must be instantiated using the WebSocket URL of the GraphQL API which is
your
Dgraph GraphQL endpoint
with https
replaced by wss
.
If your Dgraph endpoint is https://<path>
the WebSocket URL is wss://<path>
If your GraphQL API is configured to expect a JWT token in a header, you must configure the WebSocket client to pass the token. Additionally, the subscription terminates when the JWT expires.
Here are some examples of frontend clients setup.
Urql client setup in a React app
In this scenario, we’re using the
urql client and
subscriptions-transport-ws
modules.
In order to use a GraphQL subscription query in a component, you need to
- instantiate a
subscriptionClient
- instantiate a urql client with a
subscriptionExchange
using theubscriptionClient
In this example,
process.env.REACT_APP_DGRAPH_ENDPOINT
is your Dgraph GraphQL endpointprocess.env.REACT_APP_DGRAPH_WSS
is the WebSocket URLprops.token
is the JWT token of the logged-in user.
Note that we pass the JWT token in the GraphQL client using fetchOptions
and
in the WebSocket client using connectionParams
.
Assuming we use graphql-codegen, we can define a subscription query:
and use it in a React component
That’s it, the react component is able to use messages.data.queryTodo
to
display the updated list of to dos.
Apollo client setup
To learn about using subscriptions with Apollo client, see a blog post on GraphQL Subscriptions with Apollo client.
To pass the user JWT token in the Apollo client,use connectionParams
, as
follows.
Use the header expected by the Dgraph.Authorization
configuration of your
GraphQL schema.
Subscriptions to custom DQL
You can also apply @withSubscription
directive to custom DQL queries by
specifying @withSubscription
on individual DQL queries in type Query
, and
those queries are added to type subscription
.
For example, see the custom DQL query queryUserTweetCounts
below:
queryUserTweetCounts
is added to the subscription
type, allowing users to
subscribe to this query.
Currently, Dgraph only supports subscriptions on custom DQL queries. You can’t subscribe to custom HTTP queries.
Starting in release v21.03, Dgraph supports compression for subscriptions.
Dgraph uses permessage-deflate
compression if the GraphQL client’s
Sec-Websocket-Extensions
request header includes permessage-deflate
, as
follows: Sec-WebSocket-Extensions: permessage-deflate
.
Was this page helpful?