Implementing GraphQL subscriptions in a Node.js application involves using a combination of technologies and libraries to handle real-time updates. Here's a step-by-step guide on how to implement GraphQL subscriptions in a Node.js application using popular tools like Apollo Server and GraphQL subscriptions:
Setup your Node.js project: Ensure you have Node.js installed. Create a new project or navigate to your existing project directory.
bashmkdir my-graphql-app
cd my-graphql-app
npm init -y
Install required packages:
Install the necessary packages using npm. You'll need express
, apollo-server-express
, and graphql
for the basic GraphQL server. Additionally, you'll need subscriptions-transport-ws
for WebSocket support.
bashnpm install express apollo-server-express graphql subscriptions-transport-ws
Create an Express server: Set up a basic Express server with Apollo Server integration.
javascript// index.js
const express = require('express');
const { ApolloServer } = require('apollo-server-express');
const { createServer } = require('http');
const { SubscriptionServer } = require('subscriptions-transport-ws');
const { execute, subscribe } = require('graphql');
const typeDefs = /* Your GraphQL schema */;
const resolvers = /* Your GraphQL resolvers */;
const server = new ApolloServer({
typeDefs,
resolvers,
subscriptions: {
path: '/subscriptions',
},
});
const app = express();
server.applyMiddleware({ app });
const httpServer = createServer(app);
// Set up WebSocket server for subscriptions
SubscriptionServer.create(
{ execute, subscribe, schema: server.schema },
{ server: httpServer, path: '/subscriptions' }
);
httpServer.listen({ port: 4000 }, () => {
console.log(`Server ready at http://localhost:4000${server.graphqlPath}`);
console.log(`Subscriptions ready at ws://localhost:4000${server.subscriptionsPath}`);
});
Define your GraphQL schema and resolvers: Create your GraphQL schema and resolvers. Ensure you include subscription types in your schema.
javascript// schema.js
const { gql } = require('apollo-server-express');
const typeDefs = gql`
type Query {
hello: String
}
type Subscription {
messageAdded: String
}
`;
const resolvers = {
Query: {
hello: () => 'Hello, world!',
},
Subscription: {
messageAdded: {
subscribe: () => pubsub.asyncIterator('MESSAGE_ADDED'),
},
},
};
module.exports = { typeDefs, resolvers };
Handle subscriptions with PubSub:
Use the graphql-subscriptions
library's PubSub
to manage subscriptions.
javascript// index.js
const { ApolloServer, PubSub } = require('apollo-server-express');
const { createServer } = require('http');
const { SubscriptionServer } = require('subscriptions-transport-ws');
const { execute, subscribe } = require('graphql');
const { typeDefs, resolvers } = require('./schema');
const pubsub = new PubSub();
const server = new ApolloServer({
typeDefs,
resolvers,
context: { pubsub },
subscriptions: {
path: '/subscriptions',
},
});
// ...
In your resolvers, you can use pubsub.publish
to send messages to subscribers.
javascript// resolvers.js
const resolvers = {
Query: {
hello: () => 'Hello, world!',
},
Subscription: {
messageAdded: {
subscribe: () => pubsub.asyncIterator('MESSAGE_ADDED'),
},
},
Mutation: {
addMessage: (_, { message }) => {
pubsub.publish('MESSAGE_ADDED', { messageAdded: message });
return message;
},
},
};
Test your subscriptions: Start your server and test the subscriptions using a tool like GraphQL Playground or Apollo Client.
Open GraphQL Playground at http://localhost:4000/graphql
.
Run a subscription query:
graphqlsubscription {
messageAdded
}
In another tab, run a mutation to trigger the subscription:
graphqlmutation {
addMessage(message: "New message!")
}
You should see the subscription updating with the new message.
This example uses Apollo Server, Express, and subscriptions-transport-ws
for WebSocket support. Adjust the code as needed based on your specific requirements and chosen GraphQL server implementation.