Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

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.