Real-Time Notifications in Web Applications: Leveraging GraphQL Subscriptions with Apollo

Introduction

When building complex web applications, one of the key challenges is providing a seamless user experience. This includes features such as live updates or notifications that happen without requiring a full-page reload. One powerful tool to achieve this is GraphQL subscriptions, especially when combined with Apollo Client for handling the client-side logic.
GraphQL subscriptions allow clients to receive real-time updates from servers without having to poll for new data. This approach not only improves user experience but also reduces network overhead by eliminating unnecessary requests. In this article, we’ll explore how to implement real-time notifications using GraphQL subscriptions and Apollo Client in your web application.

Setting Up the Environment

Before diving into the implementation details, ensure you have the necessary tools installed:

npm install apollo-server @apollo/client
# or with yarn
yarn add apollo-server @apollo/client

Creating the Subscription Schema

First, you need to define a GraphQL schema that includes a subscription for real-time notifications. Here’s a simple example of how you might set this up:

type Notification {
  id: ID!
  message: String!
  timestamp: Time!
}
type Mutation {
  createNotification(message: String!): Notification!
}
type Subscription {
  newNotification: Notification!
}

In your server code, you’ll use Apollo Server to define the schema and set up subscriptions. Make sure to handle subscription connections and disconnections properly:

const { ApolloServer } = require('apollo-server');
const typeDefs = `
  # Your schema definition goes here (above)
`;
const resolvers = {
  Subscription: {
    newNotification: {
      connect: (parent, args, context, info) => {
        // Establish connection to database or external service
        return parent;
      },
      resolve: (parent, args, context, info) => {
        // Return the updated data when a new notification is created
        return context.db.collection('notifications').findOne();
      }
    }
  }
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
  console.log(` Server ready at ${url}`);
});

Handling Subscriptions on the Client Side

On the client side, use the useSubscription hook from Apollo Client to establish a subscription connection. This will allow you to receive real-time updates:

import { useSubscription } from '@apollo/client';
import gql from 'graphql-tag';
const NEW_NOTIFICATION_SUBSCRIPTION = gql`
  subscription NewNotification {
    newNotification @client {
      id
      message
      timestamp
    }
  }
`;
function Notification() {
  const { data, error, loading } = useSubscription(NEW_NOTIFICATION_SUBSCRIPTION);
  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;
  return (
    <div>
      <h2>Real-Time Notifications:</h2>
      {data.newNotification.map((notification) => (
        <div key={notification.id}>
          <b>{notification.message}</b> ({notification.timestamp})
        </div>
      ))}
    </div>
  );
}

This example demonstrates a basic setup for using GraphQL subscriptions with Apollo Client to implement real-time notifications in web applications. Depending on your specific needs, you might need to adjust this approach or integrate it with other features of your application.
Note: This is a simplified example and may not cover all edge cases or complexities that arise in real-world applications.