Back

GraphQL Subscriptions with Apollo Supergraph

Together with a colleague, I set up an Apollo Supergraph that includes support for GQL subscriptions.

graph TD A[Gateway\n&\n Websocket Proxy] -- HTTP --> B((GraphQL\nServer)) A -- WebSocket --> C((Subscriptions\nServer))

Details of the supergraph

We put the old GraphQL server and the subscriptions server behind the gateway server, and then we set up a WebSocket proxy server to proxy the connections to the subscriptions server.

This is the base of the gateway server:

import { ApolloServer } from "@apollo/server";
import { ApolloGateway } from "@apollo/gateway";
import { createServer } from "http";
import express from "express";
import { createServer as createProxy } from "http-proxy";

const proxy = createProxy({
  target: "ws://localhost:4002/subscriptions",
  ws: true,
  changeOrigin: true,
});

const app = express();
const httpServer = createServer(app);

const supergraphSdl = new IntrospectAndCompose({
  subgraphs: [
    {
      name: "gql",
      url: "http://localhost:4001/graphql",
    },
    {
      name: "sub",
      url: "http://localhost:4002/graphql",
    },
  ],
});

const gateway = new ApolloGateway({
  supergraphSdl,
});

const server = new ApolloServer({
  gateway,
});

httpServer.on("upgrade", (req, socket, head) => {
  proxy.ws(req, socket, head);
});

httpServer.listen(4000, () => {
  console.log(`🚀 Server ready at http://localhost:4000/graphql`);
});
Johan