This section is all about bringing realtime functionality into the app by using GraphQL subscriptions.
Subscriptions are a GraphQL feature allowing the server to send data to its clients when a specific event happens. Subscriptions are usually implemented with WebSockets, where the server holds a steady connection to the client. This means when working with subscriptions, you’re breaking the Request-Response-Cycle that was used for all previous interactions with the API. The client now initiates a steady connection with the server by specifying which event it is interested in. Every time this particular event then happens, the server uses the connection to push the expected data to the client.
When using Apollo, you need to configure your
ApolloClient with information about the subscriptions endpoint. This is done by adding another
ApolloLink to the Apollo middleware chain. This time, it’s the
WebSocketLink from the
Go and add this dependency to your app first.
Next, make sure your
ApolloClient instance knows about the subscription server.
Notice that you’re now also importing the
split function from ‘apollo-client-preset’.
You’re instantiating a
WebSocketLink that knows the subscriptions endpoint. The subscriptions endpoint in this case is similar to the HTTP endpoint, except that it uses the
ws instead of
http protocol. Notice that you’re also authenticating the websocket connection with the user’s
token that you retrieve from
split is used to “route” a request to a specific middleware link. It takes three arguments, the first one is a
test function which returns a boolean. The remaining two arguments are again of type
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:
For the app to update in realtime when new links are created, you need to subscribe to events that are happening on the
Link type. There generally are three kinds of events you can subscribe to when using Prisma:
You’ll implement the subscription in the
LinkList component since that’s where all the links are rendered.
Let’s understand what’s going on here! You’re using the
feedQuery that you have access to inside the component’s props (because you wrapped it with the
graphql container) to call
subscribeToMore. This call opens up a websocket connection to the subscription server.
You’re passing two arguments to
document: This represents the subscription query itself. In your case, the subscription will fire every time a new link is created.
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 after the event occurred.
Go ahead and implement
updateQuery next. This function works slightly differently than
update. In fact, it follows exactly 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’s sent by the server. You can then determine how to merge the subscription data into the existing state and return the updated data.
Let’s see what this looks like in action!
All you do here is retrieve the new link from the received
subscriptionData, merge it into the existing list of links and return the result of this operation.
The last thing here is to make sure that the component actually subscribes to the events by calling
componentDidMountis a so-called lifecycle method of React components that will be called once right after the component was initialized.
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:3000/. The second window you use to open a Playground and send a
post mutation. When you’re sending the mutation, you’ll see the app update in realtime! ⚡️
ATTENTION: There’s a currently a bug in the
apollo-link-wspackage that will prevent your app from running due to the following error:
Module not found: Can't resolve 'subscriptions-transport-ws' in '/.../hackernews-react-apollo/node_modules/apollo-link-ws/lib'. The workaround until it’s fixed is to manually install the
yarn add subscriptions-transport-ws. There’s also another bug in
graphql-yogawhich causes the subscription to fire multiple times (while the link is in fact only created once). After reloading the site, you’ll see the correct number of links.
Next you’ll subscribe to new votes that are submitted by other users so that the latest vote count is always visible in the app.
Similar as before, you’re calling
subscribeToMore on the
feedQuery. This time you’re passing in a subscription that asks for newly created votes. When the subscription fires, Apollo Client automatically updates the link that was voted on.
Fantastic! Your app is now ready for realtime and will immediately update links and votes whenever they’re created by other users.