@@ -8,6 +8,10 @@ const { ApolloServer, gql } = require('apollo-server-express')
|
8 | 8 | const { PubSub } = require('graphql-subscriptions')
|
9 | 9 | const merge = require('deepmerge')
|
10 | 10 |
|
| 11 | +const { SubscriptionServer } = require('subscriptions-transport-ws') |
| 12 | +const { makeExecutableSchema } = require('@graphql-tools/schema') |
| 13 | +const { execute, subscribe } = require('graphql') |
| 14 | + |
11 | 15 | function defaultValue (provided, value) {
|
12 | 16 | return provided == null ? value : provided
|
13 | 17 | }
|
@@ -27,6 +31,7 @@ module.exports = async (options, cb = null) => {
|
27 | 31 |
|
28 | 32 | // Express app
|
29 | 33 | const app = express()
|
| 34 | +const httpServer = http.createServer(app) |
30 | 35 |
|
31 | 36 | // Customize those files
|
32 | 37 | let typeDefs = load(options.paths.typeDefs)
|
@@ -64,12 +69,16 @@ module.exports = async (options, cb = null) => {
|
64 | 69 |
|
65 | 70 | typeDefs = processSchema(typeDefs)
|
66 | 71 |
|
| 72 | +// eslint-disable-next-line prefer-const |
| 73 | +let subscriptionServer |
| 74 | + |
67 | 75 | let apolloServerOptions = {
|
68 | 76 | typeDefs,
|
69 | 77 | resolvers,
|
70 | 78 | schemaDirectives,
|
71 | 79 | dataSources,
|
72 | 80 | tracing: true,
|
| 81 | +cache: 'bounded', |
73 | 82 | cacheControl: true,
|
74 | 83 | engine: !options.integratedEngine,
|
75 | 84 | // Resolvers context from POST
|
@@ -89,23 +98,15 @@ module.exports = async (options, cb = null) => {
|
89 | 98 | return contextData
|
90 | 99 | },
|
91 | 100 | // Resolvers context from WebSocket
|
92 |
| -subscriptions: { |
93 |
| -path: options.subscriptionsPath, |
94 |
| -onConnect: async (connection, websocket) => { |
95 |
| -let contextData = {} |
96 |
| -try { |
97 |
| -contextData = await autoCall(context, { |
98 |
| -connection, |
99 |
| -websocket |
100 |
| -}) |
101 |
| -contextData = Object.assign({}, contextData, { pubsub }) |
102 |
| -} catch (e) { |
103 |
| -console.error(e) |
104 |
| -throw e |
| 101 | +plugins: [{ |
| 102 | +async serverWillStart () { |
| 103 | +return { |
| 104 | +async drainServer () { |
| 105 | +subscriptionServer.close() |
| 106 | +} |
105 | 107 | }
|
106 |
| -return contextData |
107 | 108 | }
|
108 |
| -} |
| 109 | +}] |
109 | 110 | }
|
110 | 111 |
|
111 | 112 | // Automatic mocking
|
@@ -146,6 +147,36 @@ module.exports = async (options, cb = null) => {
|
146 | 147 |
|
147 | 148 | // Apollo Server
|
148 | 149 | const server = new ApolloServer(apolloServerOptions)
|
| 150 | + |
| 151 | +const schema = makeExecutableSchema({ |
| 152 | +typeDefs: apolloServerOptions.typeDefs, |
| 153 | +resolvers: apolloServerOptions.resolvers, |
| 154 | +schemaDirectives: apolloServerOptions.schemaDirectives |
| 155 | +}) |
| 156 | + |
| 157 | +subscriptionServer = SubscriptionServer.create({ |
| 158 | +schema, |
| 159 | +execute, |
| 160 | +subscribe, |
| 161 | +onConnect: async (connection, websocket) => { |
| 162 | +let contextData = {} |
| 163 | +try { |
| 164 | +contextData = await autoCall(context, { |
| 165 | +connection, |
| 166 | +websocket |
| 167 | +}) |
| 168 | +contextData = Object.assign({}, contextData, { pubsub }) |
| 169 | +} catch (e) { |
| 170 | +console.error(e) |
| 171 | +throw e |
| 172 | +} |
| 173 | +return contextData |
| 174 | +} |
| 175 | +}, { |
| 176 | +server: httpServer, |
| 177 | +path: options.subscriptionsPath |
| 178 | +}) |
| 179 | + |
149 | 180 | await server.start()
|
150 | 181 |
|
151 | 182 | // Express middleware
|
@@ -160,9 +191,7 @@ module.exports = async (options, cb = null) => {
|
160 | 191 | })
|
161 | 192 |
|
162 | 193 | // Start server
|
163 |
| -const httpServer = http.createServer(app) |
164 | 194 | httpServer.setTimeout(options.timeout)
|
165 |
| -server.installSubscriptionHandlers(httpServer) |
166 | 195 |
|
167 | 196 | httpServer.listen({
|
168 | 197 | host: options.host || 'localhost',
|
|
0 commit comments