0
0
GraphqlHow-ToBeginner · 4 min read

How to Create Subscription in GraphQL: Syntax and Example

To create a subscription in GraphQL, define a subscription type in your schema with fields that clients can listen to for real-time updates. Implement resolver functions that push data to subscribed clients when events occur, using a pub/sub system or similar mechanism.
📐

Syntax

A GraphQL subscription is defined in the schema using the subscription keyword. Each field inside the subscription type represents an event clients can subscribe to. The subscription resolver returns an async iterator that pushes data to clients.

Key parts:

  • subscription: declares subscription type
  • Field name: event name clients listen to
  • Return type: the data sent on event
  • Resolver: returns async iterator for updates
graphql
type Subscription {
  messageAdded: Message
}

// Resolver example
const resolvers = {
  Subscription: {
    messageAdded: {
      subscribe: () => pubsub.asyncIterator(['MESSAGE_ADDED'])
    }
  }
};
💻

Example

This example shows a simple GraphQL subscription that notifies clients when a new message is added. It uses a pub/sub system to publish events and an async iterator to send updates.

javascript
const { ApolloServer, gql, PubSub } = require('apollo-server');

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

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

  type Query {
    messages: [Message!]
  }

  type Subscription {
    messageAdded: Message
  }

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

const messages = [];

const resolvers = {
  Query: {
    messages: () => messages
  },
  Mutation: {
    addMessage: (parent, { content }) => {
      const message = { id: messages.length + 1, content };
      messages.push(message);
      pubsub.publish(MESSAGE_ADDED, { messageAdded: message });
      return message;
    }
  },
  Subscription: {
    messageAdded: {
      subscribe: () => pubsub.asyncIterator([MESSAGE_ADDED])
    }
  }
};

const server = new ApolloServer({ typeDefs, resolvers });

server.listen().then(({ url }) => {
  console.log(`Server ready at ${url}`);
});
Output
Server ready at http://localhost:4000/
⚠️

Common Pitfalls

Common mistakes when creating subscriptions include:

  • Not using an async iterator in the subscription resolver, which is required to push updates.
  • Forgetting to publish events to the pub/sub system, so clients never receive updates.
  • Trying to use subscriptions without a WebSocket or transport that supports real-time updates.
  • Not defining the Subscription type in the schema.

Always ensure your server supports WebSocket connections and your client uses a compatible subscription client.

javascript
/* Wrong resolver (missing async iterator) */
const resolvers = {
  Subscription: {
    messageAdded: () => {
      // This returns data once, not a stream
      return { id: 1, content: 'Hello' };
    }
  }
};

/* Correct resolver */
const resolvers = {
  Subscription: {
    messageAdded: {
      subscribe: () => pubsub.asyncIterator(['MESSAGE_ADDED'])
    }
  }
};
📊

Quick Reference

ConceptDescription
subscription typeDefines events clients can subscribe to
async iteratorResolver must return this to stream updates
pubsub.publishUsed to send events to subscribers
WebSocketTransport protocol needed for real-time updates
client subscriptionClient must use subscription query to listen

Key Takeaways

Define a subscription type in your GraphQL schema with event fields.
Subscription resolvers must return an async iterator to stream data.
Use a pub/sub system to publish events that trigger subscription updates.
Ensure your server and client support WebSocket for real-time communication.
Avoid returning static data in subscription resolvers; always use async iterators.