Schema, Resolvers & PubSub
Schema & Resolver
type Subscription {
messageAdded(channelId: ID!): Message
}
type Mutation {
sendMessage(channelId: ID!, text: String!): Message
}const { PubSub, withFilter } = require('graphql-subscriptions');
const pubsub = new PubSub();
const resolvers = {
Mutation: {
sendMessage: async (_, { channelId, text }) => {
const message = await db.messages.create({ channelId, text });
// Publishing is what triggers any active subscription resolvers
pubsub.publish('MESSAGE_ADDED', { messageAdded: message });
return message;
},
},
Subscription: {
messageAdded: {
// subscribe returns an async iterator yielding a new value per event
subscribe: withFilter(
() => pubsub.asyncIterator('MESSAGE_ADDED'),
// Only deliver to clients subscribed to THIS specific channel —
// without this, every subscriber gets every channel's messages
(payload, variables) => payload.messageAdded.channelId === variables.channelId
),
},
},
};Client Setup (Apollo Client)
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { createClient } from 'graphql-ws';
import { split, HttpLink, ApolloClient, InMemoryCache } from '@apollo/client';
const httpLink = new HttpLink({ uri: '/graphql' });
const wsLink = new GraphQLWsLink(createClient({
url: 'wss://api.example.com/graphql',
connectionParams: { authToken: getToken() }, // sent once, at connection time
}));
// Route subscription operations to the WebSocket link, everything else to HTTP —
// they need fundamentally different transport mechanics
const splitLink = split(
({ query }) => {
const def = getMainDefinition(query);
return def.kind === 'OperationDefinition' && def.operation === 'subscription';
},
wsLink,
httpLink,
);
const client = new ApolloClient({ link: splitLink, cache: new InMemoryCache() });Using the Subscription
function ChatWindow({ channelId }) {
const { data, loading } = useSubscription(MESSAGE_ADDED_SUBSCRIPTION, {
variables: { channelId },
});
useEffect(() => {
if (data) addMessageToList(data.messageAdded);
}, [data]);
return <MessageList />;
}Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free