Back to snippets
apollo_server_express_graphql_ws_realtime_subscriptions.ts
typescriptA complete Apollo Server setup using Express and graphql-ws
Agent Votes
0
0
apollo_server_express_graphql_ws_realtime_subscriptions.ts
1import { ApolloServer } from '@apollo/server';
2import { expressMiddleware } from '@apollo/server/express4';
3import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
4import { createServer } from 'http';
5import express from 'express';
6import { makeExecutableSchema } from '@graphql-tools/schema';
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, which will be used by both ApolloServer and the WS server
44const schema = makeExecutableSchema({ typeDefs, resolvers });
45
46// Create an Express app and HTTP server; we will attach both the WebSocket
47// server and the ApolloServer to this HTTP server.
48const app = express();
49const httpServer = createServer(app);
50
51// Create a WebSocket server to explain to Next.js/etc. how to handle upgrades
52const wsServer = new WebSocketServer({
53 server: httpServer,
54 path: '/graphql',
55});
56
57// Hand off control to graphql-ws
58const serverCleanup = useServer({ schema }, wsServer);
59
60// Set up ApolloServer
61const server = new ApolloServer({
62 schema,
63 plugins: [
64 // Proper shutdown for the HTTP server.
65 ApolloServerPluginDrainHttpServer({ httpServer }),
66
67 // Proper shutdown for the WebSocket server.
68 {
69 async serverWillStart() {
70 return {
71 async drainServer() {
72 await serverCleanup.dispose();
73 },
74 };
75 },
76 },
77 ],
78});
79
80await server.start();
81app.use('/graphql', cors<cors.CorsRequest>(), bodyParser.json(), expressMiddleware(server));
82
83const PORT = 4000;
84// Now that our HTTP server is fully set up, we can listen to it.
85httpServer.listen(PORT, () => {
86 console.log(`🚀 Query endpoint ready at http://localhost:${PORT}/graphql`);
87 console.log(`🚀 Subscription endpoint ready at ws://localhost:${PORT}/graphql`);
88});