The goal of this chapter is to add realtime functionality to the app using GraphQL subscriptions. In particular, you’re going to make sure that when other users vote on a link, the link’s vote count updates immediately in the app for all other users without the need to refresh the page.
GraphQL subscriptions allow you to add event-based realtime functionality to your app. A client can subscribe to specific events that are happening on the server-side. Then, whenenever that event actually happens, the server will send the corresponding data over to the client.
Events usually refer to mutations, so typically we’re talking about events where data was created, updated or deleted.
Subscriptions are somewhat different from queries and mutations, since they don’t follow a request-response-cycle but instead represent a stream of data. The most common way to implement subscriptions is by using WebSockets, where the server maintains a steady connection to the subscribed clients that it uses to send over the data upon each event.
To get a feeling for how subscriptions work, you can also directly try them out in a Playground!
Subscription support was only added to Relay with the release of Relay Modern. Client can now use the
requestSubscription function to initiate a subscription.
requestSubscription works very similar to the
commitMutation function as it also allows you to implement an
updater functions to specify how you want the cache to update based on the new data that was received from the server.
However, in order to get
requestSubscription to work, you also need to configure your Relay
Environment accordingly and provide the URL for your subscription endpoint. If subscriptions are implemented with WebSockets, the subscriptions URL will contain the
wss protocol instead of
Graphcool generally exposes two different GraphQL APIs whose type definitions slitghly vary:
Currently, subscriptions are only supported for the Simple API. However, you can still use subscriptions with the Relay API by making some manual adjustments to the
schema.graphql which you feed into the
Notice that we already did these manual adjustments for you and you already have them in your project as you imported the project from this URL in chapter 3. If you’re interested in what these changes actually look like, take a look at the
Subscription type in
The first thing you need to do to get subscriptions to work is add websocket support to your project.
This package contains the
SubscriptionClient that you need to setup subscriptions on the frontend. The
SubscriptionClient is a good fit in this case as it implements the same protocol as the subscriptions API from Graphcool.
Next you’ll have to configure your Relay
Environment and tell it about the additional endpoint that you want to use for subscriptions. The way how this works is actually by adding a second function to the creation of the
Network. This function knows about the subscription endpoint and is able to initiate and maintain a connection to it.
Let’s quickly understand what’s going on there:
Network.create(), you just pull out the code of that closure and store it in a variable called
fetchQuery. Note that you’ll have to replace
__PROJECT_ID__again with your actual project ID.
Networkneeds in order to be able to talk to the subscriptions endpoint. You’re using the
SubscriptionClientin that function to initiate and maintain a connection to the given endpoint. The
configthat’s passed into the function carrys the subscription query which determines what event the client wants to subscribe to and what data it wants to receive. Note that again you need to replace the placeholder for
__PROJECT_ID__with the actual ID of your Graphcool project.
fetchQuery(which is the same code as before but stored in a variable) and
setupSubscriptionand use them to create the
Network, which then will be used to instantiate the Relay
If you’re not sure what your Graphcool project ID is that you need to replace the
__PROJECT_ID__, you can open
project.graphcooland check its frontmatter or execute
graphcool endpointsin a terminal to see the endpoints for the Relay API and Subscriptions API.
Awesome, your app is now capable of using subscriptions! ⚡️
Similar to what you did with the mutations before, you’ll implement each subscription in a dedicated file to provide a more convenient wrapper around the
requestSubscription function that’s provided by Relay.
Let’s take a closer look at the subscription query that you’re storing in
Votethat was created, this information is represented by the
nodefield. Every time a vote is submitted by another user, the server will send information about that new vote, including the
userwho created it and the total number of votes on the corresponding link (
requestSubscriptionfunction. Notice that you’re using the
updaterto increase the number of votes for the link that was voted on.
Now that you have all required infrastructure setup, you can go ahead and actually iniate a subscription! For our project, it’s not too important where exactly the subscription is invoked as there are no context-dependent arguments that the subscription needs. However, it is important that the subscription only gets invoked once, so you don’t want to put it into the
Link component where it would be invoked as many times as
Link elements are rendered. You’ll therefore put it into the
Then of course you also need to add the corresponding import.
Before you’re running the app, you’ll need to invoke the Relay Compiler again so it can compile the
graphql-tagged code inside
All right, you can now run the app with
yarn start to test your subscription. The best way to test subscriptions is to use two different windows (or simply tabs) that are both running the app. If you then submit a vote in one window, the app should automatically update in the second window as well. 🎉