Back to snippets

apollo_server_express_websocket_graphql_subscriptions_quickstart.ts

typescript

Sets up an Apollo Server with Express and WebSocket support to han

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