Realtime Updates In GraphQL Apollo Server using Subscriptions
Most of the times, users get updated data on browser reloads. This drastically affects the user experience (UX). Users often expect to see the updated data instantly without any intervention. This is what realtime applications intend to do. We can achieve this with our GraphQL API using what is called subscriptions.
This is probably one of the most important features of GraphQL. GraphQL Subscriptions push the data from server to the clients who intends to listen to the real time updates from the server. They have similar syntax to query and send response to the subscribed client each time a dataset is published.
# What’s cooking?
We have set the stage and implemented CRUD queries and mutations and built a simple application using Express Server and Apollo in the past. We will take that API forward and integrate subscriptions to it. We will define various subscriptions that will notify clients each time a user inserts, updates or deletes a company.
And later, we will also build a react app to implement GraphQL subscriptions. For now, let us start working on our Company API. You can also clone the github repo for reference.
# Define Subscriptions
We can add subscriptions in the schema
in same way as we did for queries and mutations.
# src/schema.js
...
const typeDefs = `
...
type Mutation {
...
}
type Subscription {
companyAdded: Company,
companyEdited: Company,
companyDeleted: Company
}
`;
...
Here we defining a root subscription type for insert, update and delete operation. It will return a Company
type.
# GraphQL Apollo Subscription Resolver with WebSocket
Realtime client-server usually involves web sockets in javaScript. But don’t worry we won’t have to build a web socket now! We will utilize third party library subscriptions-transport-ws
for it.
For now, we need to create a PubSub
environment in our API where server can publish event and clients can subscribe to those events. graphql-subscriptions
can help us build this environment. So let us first install both of these packages:
npm install subscriptions-transport-ws graphql-subscriptions --save
graphql-subscriptions
has similar implementation to redux. Redux has typical reducers and actions. We can follow that pattern but since we need only one subscription, we will not get into complexity.
# src/resolvers.js
import { PubSub } from 'graphql-subscriptions';
...
const ADD_COMPANY = 'addCompany';
const EDIT_COMPANY = 'editCompany';
const DELETE_COMPANY = 'deleteCompany';
const pubsub = new PubSub();
We just imported PubSub
from graphql-subscriptions
and instantiated it. We also define a redux type equivalent addCompany
, editCompany
and deleteCompany
which are kind of event name.
# src/resolvers.js
...
const resolvers = {
Query: {
...
},
Mutation: {
addCompany: (root, { name }) => {
...
pubsub.publish(ADD_COMPANY, { companyAdded: newCo });
return newCo;
},
updateCompany: (root, { id, name }) => {
...
pubsub.publish(EDIT_COMPANY, { companyEdited: updateCo });
return updateCo;
},
deleteCompany: (root, { id }) => {
...
pubsub.publish(DELETE_COMPANY, { companyDeleted: deleteCo });
return deleteCo;
},
}
};
module.exports = resolvers;
In all our mutations, we are publishing an event for client to listen with the help of pubsub
. The companyAdded
and others come from the schema
we declared earlier.
# src/resolvers.js
...
const resolvers = {
Query: {
...
},
Mutation: {
...
},
Subscription: {
companyAdded: {
subscribe: () => pubsub.asyncIterator(ADD_COMPANY)
},
companyEdited: {
subscribe: () => pubsub.asyncIterator(EDIT_COMPANY)
},
companyDeleted: {
subscribe: () => pubsub.asyncIterator(DELETE_COMPANY)
}
}
};
...
And finally, we are defining a subscriptions which returns asyncIterator
that emits realtime events to the clients.
# The GraphQL Apollo Subscription Server
The final step is to map GraphQL subscriptions to the server so that it can emit relevant events and notify client about it. As discussed, we will use subscriptions-transport-ws
websocket server. Let us go ahead and implement it in server.js
# server.js
...
import { execute, subscribe } from 'graphql';
import { createServer } from 'http';
import { SubscriptionServer } from 'subscriptions-transport-ws';
...
As you can see, we just imported relevant components from the libraries.
const app = express();
const ws = createServer(app);
...
app.use('/graphql', bodyParser.json(), graphqlExpress({
schema
}));
app.use('/graphiql', graphiqlExpress({
endpointURL: '/graphql',
subscriptionsEndpoint: `ws://localhost:${PORT}/subscriptions`
}));
Above, we are wrapping the express server within createServer
. This typically opens a WebSocket connection where we then listen to any GraphQL subscriptions. We configure GraphiQL to listen to subscriptions.
ws.listen(PORT, () => {
console.log('GraphQL API Server up and running at localhost:' + PORT);
new SubscriptionServer({
execute,
subscribe,
schema
}, {
server: ws,
path: '/subscriptions',
});
});
We can also initiate a new SubscriptionServer
to handle subscriptions and thus we can start testing them immediately.
# Testing GraphQL API for Realtime Updates
The moment you’ve been waiting for after some serious coding! You can test the following subscription:
subscription NewCompanySub{
companyAdded {
id
name
}
}
http://localhost:8080/graphiql

To test whether we receive instant data or not, open the http://localhost:8080/graphiql
in new browser tab side by side. You can test CRUD operation here. For instance, the create operation:
mutation AddNewCo {
addCompany (name: "HP"){
name
}
}
Here’s the result:

Conclusion:
In this tutorial, we took the GraphQL API forward and integrated subscriptions to it. It enables realtime updates. We also tested the API in GraphiQL and thus completed the application.
Questions & Comments:
Hope you enjoyed the tutorial. If you face any issues or have any questions/suggestion, don’t hesitate to share in comment section below.