GraphQL - Real-time Chat with GraphQL
Building a Real-time Chat Application
This guide will walk you through the process of building a real-time chat application using GraphQL and subscriptions. You will learn how to set up your server, define schemas, and implement chat functionalities.
Key Points:
- Understand GraphQL subscriptions for real-time features.
- Implement user authentication for chat applications.
- Manage state with Apollo Client in a React app.
Step 1: Setting Up Your GraphQL Server
Begin by setting up a GraphQL server using Apollo Server. Install the necessary packages:
npm install apollo-server graphql
Create your server and define the initial schema:
const { ApolloServer, gql } = require('apollo-server');
const { PubSub } = require('graphql-subscriptions');
const pubsub = new PubSub();
const typeDefs = gql`
type Message {
id: ID!
content: String!
user: String!
}
type Query {
messages: [Message]
}
type Mutation {
sendMessage(content: String!, user: String!): Message
}
type Subscription {
messageSent: Message
}
`;
const resolvers = {
Query: {
messages: () => {
// Logic to retrieve messages
},
},
Mutation: {
sendMessage: (parent, { content, user }) => {
const message = { id: String(messages.length + 1), content, user };
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}`);
});
Step 2: Implementing Message Storage
You can store messages in memory for simplicity:
const messages = [];
Update the resolver to return the stored messages:
Query: {
messages: () => messages,
},
Step 3: Setting Up the Client
Set up your client application using Apollo Client to fetch and send messages:
npm install @apollo/client graphql
Create an Apollo Client setup:
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
const client = new ApolloClient({
uri: 'http://localhost:4000/graphql',
cache: new InMemoryCache(),
});
Step 4: Creating the Chat Interface
Create components to display messages and send new messages:
import React, { useEffect, useState } from 'react';
import { useQuery, useMutation, gql } from '@apollo/client';
const GET_MESSAGES = gql`
query GetMessages {
messages {
id
content
user
}
}
`;
const SEND_MESSAGE = gql`
mutation SendMessage($content: String!, $user: String!) {
sendMessage(content: $content, user: $user) {
id
content
user
}
}
`;
const MESSAGE_SENT = gql`
subscription {
messageSent {
id
content
user
}
}
`;
const Chat = () => {
const { loading, error, data, subscribeToMore } = useQuery(GET_MESSAGES);
const [sendMessage] = useMutation(SEND_MESSAGE);
const [message, setMessage] = useState('');
const [user, setUser] = useState('User1'); // Replace with actual user data
useEffect(() => {
subscribeToMore({
document: MESSAGE_SENT,
updateQuery: (prev, { subscriptionData }) => {
if (!subscriptionData.data) return prev;
const newMessage = subscriptionData.data.messageSent;
return {
...prev,
messages: [...prev.messages, newMessage],
};
},
});
}, [subscribeToMore]);
const handleSendMessage = () => {
sendMessage({ variables: { content: message, user } });
setMessage('');
};
if (loading) return Loading...
;
if (error) return Error: {error.message}
;
return (
<div>
<h2>Chat Room</h2>
<ul>
{data.messages.map(msg => (
<li key={msg.id}><strong>{msg.user}:</strong> {msg.content}</li>
))}
</ul>
<input
type="text"
value={message}
onChange={e => setMessage(e.target.value)}
placeholder="Type a message..."
/>
<button onClick={handleSendMessage}>Send</button>
</div>
);
};
export default Chat;
Step 5: Conclusion
You have successfully built a real-time chat application using GraphQL! This application can be further enhanced with features like user authentication, message persistence, and improved UI/UX design.