How to Implement Chat Using GraphQL: Simple Guide
To implement chat using
GraphQL, define queries to fetch messages, mutations to send messages, and subscriptions to receive real-time updates. Use subscriptions with WebSocket to push new messages instantly to clients.Syntax
A chat system in GraphQL typically uses three main parts:
- Query: To get existing chat messages.
- Mutation: To send or add a new message.
- Subscription: To listen for new messages in real-time.
Subscriptions require a WebSocket connection to push updates from the server to clients.
graphql
type Message { id: ID! content: String! sender: String! timestamp: String! } type Query { messages: [Message!]! } type Mutation { sendMessage(content: String!, sender: String!): Message! } type Subscription { messageSent: Message! }
Example
This example shows a simple GraphQL schema and resolver setup for a chat system. It supports fetching messages, sending new messages, and receiving live updates when new messages arrive.
javascript
const { ApolloServer, gql, PubSub } = require('apollo-server'); const pubsub = new PubSub(); const MESSAGE_SENT = 'MESSAGE_SENT'; const typeDefs = gql` type Message { id: ID! content: String! sender: String! timestamp: String! } type Query { messages: [Message!]! } type Mutation { sendMessage(content: String!, sender: String!): Message! } type Subscription { messageSent: Message! } `; let messages = []; const resolvers = { Query: { messages: () => messages, }, Mutation: { sendMessage: (_, { content, sender }) => { const message = { id: String(messages.length + 1), content, sender, timestamp: new Date().toISOString(), }; messages.push(message); pubsub.publish(MESSAGE_SENT, { messageSent: message }); return message; }, }, Subscription: { messageSent: { subscribe: () => pubsub.asyncIterator([MESSAGE_SENT]), }, }, }; 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 implementing chat with GraphQL include:
- Not setting up
subscriptionsproperly with WebSocket, so real-time updates don't work. - Forgetting to publish events after a mutation, so subscribers never get notified.
- Using queries alone without subscriptions, which means clients must poll for new messages instead of receiving live updates.
- Not handling message IDs or timestamps correctly, causing duplicate or unordered messages.
javascript
/* Wrong: Mutation does not publish event */ const resolversWrong = { Mutation: { sendMessage: (_, { content, sender }) => { const message = { id: '1', content, sender, timestamp: new Date().toISOString() }; messages.push(message); // Missing pubsub.publish here return message; }, }, }; /* Right: Mutation publishes event */ const resolversRight = { Mutation: { sendMessage: (_, { content, sender }) => { const message = { id: '1', content, sender, timestamp: new Date().toISOString() }; messages.push(message); pubsub.publish(MESSAGE_SENT, { messageSent: message }); return message; }, }, };
Quick Reference
Tips for implementing chat with GraphQL:
- Use
Queryto load existing messages. - Use
Mutationto send new messages and publish events. - Use
Subscriptionwith WebSocket for real-time message updates. - Ensure unique IDs and timestamps for messages.
- Test subscriptions with a client that supports WebSocket (e.g., Apollo Client).
Key Takeaways
Use GraphQL subscriptions with WebSocket to enable real-time chat updates.
Publish events in mutations to notify subscribers of new messages.
Queries fetch existing messages, mutations add messages, subscriptions push live updates.
Ensure message data includes unique IDs and timestamps for proper ordering.
Test your chat system with clients that support GraphQL subscriptions.