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 apollo-link-ws
package.
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-link’.
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 localStorage
.
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 ApolloLink
. If test
returns 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 authLink.concat(httpLink)
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:
Link
is createdLink
is updatedLink
is deletedYou’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 <Query />
component as always but now you’re using subscribeToMore
received as prop into the component’s render prop function. Calling _subscribeToNewLinks
with its respective subscribeToMore
function you make sure that the component actually subscribes to the events. This call opens up a websocket connection to the subscription server.
You’re passing two arguments to subscribeToMore
:
document
: This represents the subscription query itself. In your case, the subscription will fire every time a new link is created.updateQuery
: Similar to cache update
prop, 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. 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. All you’re doing inside updateQuery
is retrieving the new link from the received subscriptionData
, merging it into the existing list of links and returning 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: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-ws
package 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 thesubscriptions-transport-ws
package withyarn add subscriptions-transport-ws
.
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
but now using NEW_VOTES_SUBSCRIPTION
as document. 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.