Blog/GraphQL Subscriptions: Real-time Data with Apollo Server

GraphQL Subscriptions: Real-time Data with Apollo Server

GraphQL subscriptions enable real-time updates in your applications. Unlike queries and mutations, subscriptions maintain an active connection to your server, pushing updates whenever data changes. Here's how to set them up with Apollo Server.

Setting Up the Server

First, configure Apollo Server with WebSocket support for subscriptions:

import { ApolloServer } from '@apollo/server'
import { expressMiddleware } from '@apollo/server/express4'
import { createServer } from 'http'
import { WebSocketServer } from 'ws'
import { useServer } from 'graphql-ws/lib/use/ws'

const httpServer = createServer(app)

const wsServer = new WebSocketServer({
  server: httpServer,
  path: '/graphql',
})

const serverCleanup = useServer({ schema }, wsServer)

const server = new ApolloServer({
  schema,
  plugins: [
    {
      async serverWillStart() {
        return {
          async drainServer() {
            await serverCleanup.dispose()
          },
        }
      },
    },
  ],
})

Defining a Subscription

Create a subscription type in your schema and implement the resolver using PubSub:

import { PubSub } from 'graphql-subscriptions'

const pubsub = new PubSub()
const MESSAGE_ADDED = 'MESSAGE_ADDED'

const typeDefs = `
  type Message {
    id: ID!
    content: String!
    user: String!
  }

  type Subscription {
    messageAdded: Message!
  }

  type Mutation {
    addMessage(content: String!, user: String!): Message!
  }
`

const resolvers = {
  Subscription: {
    messageAdded: {
      subscribe: () => pubsub.asyncIterator([MESSAGE_ADDED]),
    },
  },
  Mutation: {
    addMessage: (_, { content, user }) => {
      const message = { id: Date.now(), content, user }
      pubsub.publish(MESSAGE_ADDED, { messageAdded: message })
      return message
    },
  },
}