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`);
});