patterntypescriptgraphqlMajor
GraphQL subscriptions over WebSocket — setup and gotchas with graphql-ws
Viewed 0 times
graphql-ws 5.x, Apollo Server 4.x
subscriptionsWebSocketgraphql-wsreal-timepubsubasyncIterator
Error Messages
Problem
Setting up GraphQL subscriptions requires a separate WebSocket transport. The older
subscriptions-transport-ws library is abandoned and has known security issues. Apollo Server's built-in subscription support changed multiple times across major versions.Solution
Use
graphql-ws (not the deprecated subscriptions-transport-ws) with Apollo Server 4+.import { createServer } from 'http';
import { WebSocketServer } from 'ws';
import { useServer } from 'graphql-ws/lib/use/ws';
import { makeExecutableSchema } from '@graphql-tools/schema';
const schema = makeExecutableSchema({ typeDefs, resolvers });
const httpServer = createServer(app);
const wsServer = new WebSocketServer({ server: httpServer, path: '/graphql' });
useServer(
{
schema,
context: async (ctx) => buildContext(ctx.connectionParams),
},
wsServer
);
// Subscription resolver
const resolvers = {
Subscription: {
messageAdded: {
subscribe: (_root, { roomId }, ctx) =>
pubsub.asyncIterator(`ROOM_${roomId}`),
},
},
};Why
graphql-ws implements the newer graphql-ws protocol (vs the legacy graphql-transport-ws protocol). It handles connection init, ping/pong, and proper cleanup. Apollo Client 3+ supports it natively.Gotchas
- subscriptions-transport-ws is unmaintained — do not use it for new projects
- WebSocket context runs per-connection, not per-operation — store auth in connection context
- PubSub from graphql-subscriptions is in-memory only — use Redis PubSub for multi-process deployments
- Apollo Client requires explicitly setting wsLink and splitting HTTP vs WS links by operation type
Context
Adding real-time subscription support to a GraphQL server
Revisions (0)
No revisions yet.