Realtime Updates with GraphQL Subscriptions

This section is all about bringing real-time functionality into the app by using GraphQL subscriptions.

What are GraphQL Subscriptions?

Subscriptions are a GraphQL feature that allows the server to send data to the clients when a specific event happens on the backend. Subscriptions are usually implemented with WebSockets, where the server holds a steady connection to the client. That is, the Request-Response-Cycle that we used for all previous interactions with the API is not used for subscriptions. Instead, the client initially opens up a steady connection to the server by specifying which event it is interested in. Every time this particular event happens, the server uses the connection to push the data that’s related to the event to the client.

Subscriptions with Apollo

When using Apollo, you need to configure your ApolloClient with information about the subscriptions endpoint. This is done by using functionality from the subscriptions-transport-ws npm module.

Go ahead and add this dependency to your app first.

Next, make sure your ApolloClient instance knows about the subscription server.

You’re instantiating a WebSocketLink that knows the endpoint for the Subscriptions API. Notice that you’re also authenticating the websocket connection with the user’s token that you retrieve from localStorage.

split is used to “route” a request to a specific middleware link. It takes three arguments, the first one is a test function returning a boolean, the remaining two are again of type ApolloLink. If that boolean is true, the request will be forwarded to the link passed as the second argument. If false, to the third one.

In your case, the test function is checking whether the requested operation is a subscription. If this is the case, it will be forwarded to the wsLink, otherwise (if it’s a query or mutation), the httpLinkWithAuthToken will take care of it:

Apollo Link
Picture taken from Apollo Link: The modular GraphQL network stack by Evans Hauser

Now you need to replace the placeholder __SUBSCRIPTION_API_ENDPOINT__ with the endpoint for the Subscriptions API.

The endpoints for the Subscriptions API generally are of the form: wss://subscriptions.graph.cool/v1/__SERVICE_ID__.

Subscribing to new Links

For the app to update in real-time when new links are created, you need to subscribe to events that are happening on the Link type. There are three kinds of events you can subscribe to:

  • a new Link is created
  • an existing Link is updated
  • an existing Link is deleted

First, you need to add a subscription to src/app/graphql.ts:

You’ll implement this subscription in the LinkListComponent since that’s where all the links are rendered.

Let’s understand what’s going on here! You’re using the subscribeToMore function in ApolloQueryObservable returned by the watchQuerythat will open up a WebSocket connection to the subscription server.

You’re passing an array to SubscribeToMoreOptions:

  1. Each object within the array contains a document property: This represents the subscription itself. In your case, the subscription will fire for CREATED events on the Link type, i.e., every time a new link is created.
  2. The other property is updateQuery: Similar to update, this function allows you to determine how the store should be updated with the information that was sent by the server.

Go ahead and implement updateQuery next. This function works slightly differently than update. In fact, it follows the same principle as a Redux reducer: It takes as arguments the previous state (of the query that subscribeToMore was called on) and the subscription data that are sent by the server. You can then determine how to merge the subscription data into the existing state and return the updated version.

Let’s see what this looks like in action!

All you do here is retrieve the new link from the subscription data (subscriptionData.Link.node), merge it into the existing list of links and return the result of this operation.

Awesome, that’s it! You can test your implementation by opening two browser windows. In the first window, you have your application running on http://localhost:4200/. The second window you use to open a Playground and send a createLink mutation. When you’re sending the mutation, you’ll see the app update in real-time! ⚡️

Subscribing to new Votes

Next, you’ll subscribe to new votes that are emitted by other users as well so that the latest vote count is always visible in the app.

First, you need to add another subscription to src/app/graphql.ts:

You’ll also implement this subscription in the LinkList component since that’s where all the links are rendered.

Similar to before, you’re calling subscribeToMore on the allLinks query. This time you’re passing in a subscription that asks for newly created votes. In updateQuery, you’re then adding the information about the new vote to the cache by first looking for the Link that was just voted on and then updating its votes with the Vote element that was sent from the server.

Fantastic! Your app is now ready for real-time and will immediately update links and votes whenever they’re created by other users.

Unlock the next chapter
What transport does Apollo use to implement subscriptions?
WebSockets
TCP
UDP
HTTP 2