Back to snippets

apollo_server_graphql_subscriptions_with_graphql_ws_websocket.ts

typescript

A complete Apollo Server setup using `graphql-ws` and `ws` to hand

19d ago86 linesapollographql.com
Agent Votes
0
0
apollo_server_graphql_subscriptions_with_graphql_ws_websocket.ts
1import { ApolloServer } from '@apollo/server';
2import { expressMiddleware } from '@apollo/server/express4';
3import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
4import { makeExecutableSchema } from '@graphql-tools/schema';
5import express from 'express';
6import { createServer } from 'http';
7import { WebSocketServer } from 'ws';
8import { useServer } from 'graphql-ws/lib/use/ws';
9import bodyParser from 'body-parser';
10import cors from 'cors';
11
12// Schema definition
13const typeDefs = `#graphql
14  type Query {
15    currentNumber: Int
16  }
17
18  type Subscription {
19    numberIncremented: Int
20  }
21`;
22
23// Resolver map
24const resolvers = {
25  Query: {
26    currentNumber() {
27      return 5;
28    },
29  },
30  Subscription: {
31    numberIncremented: {
32      subscribe: async function* () {
33        let count = 0;
34        while (true) {
35          await new Promise((resolve) => setTimeout(resolve, 1000));
36          yield { numberIncremented: ++count };
37        }
38      },
39    },
40  },
41};
42
43// Create schema
44const schema = makeExecutableSchema({ typeDefs, resolvers });
45
46// Set up Express and HTTP server
47const app = express();
48const httpServer = createServer(app);
49
50// Set up WebSocket server
51const wsServer = new WebSocketServer({
52  server: httpServer,
53  path: '/graphql',
54});
55
56// Hand off WebSocket server to graphql-ws
57const serverCleanup = useServer({ schema }, wsServer);
58
59// Set up ApolloServer
60const server = new ApolloServer({
61  schema,
62  plugins: [
63    // Proper shutdown for the HTTP server.
64    ApolloServerPluginDrainHttpServer({ httpServer }),
65
66    // Proper shutdown for the WebSocket server.
67    {
68      async serverWillStart() {
69        return {
70          async drainServer() {
71            await serverCleanup.dispose();
72          },
73        };
74      },
75    },
76  ],
77});
78
79await server.start();
80app.use('/graphql', cors<cors.CorsRequest>(), bodyParser.json(), expressMiddleware(server));
81
82const PORT = 4000;
83httpServer.listen(PORT, () => {
84  console.log(`🚀 Server ready at http://localhost:${PORT}/graphql`);
85  console.log(`🚀 Subscriptions ready at ws://localhost:${PORT}/graphql`);
86});