@@ -8,6 +8,10 @@ const { ApolloServer, gql } = require('apollo-server-express')
88const { PubSub} = require ( 'graphql-subscriptions' )
99const merge = require ( 'deepmerge' )
1010
11+ const { SubscriptionServer} = require ( 'subscriptions-transport-ws' )
12+ const { makeExecutableSchema} = require ( '@graphql-tools/schema' )
13+ const { execute, subscribe} = require ( 'graphql' )
14+
1115function defaultValue ( provided , value ) {
1216return provided == null ?value :provided
1317}
@@ -27,6 +31,7 @@ module.exports = async (options, cb = null) => {
2731
2832// Express app
2933const app = express ( )
34+ const httpServer = http . createServer ( app )
3035
3136// Customize those files
3237let typeDefs = load ( options . paths . typeDefs )
@@ -64,12 +69,16 @@ module.exports = async (options, cb = null) => {
6469
6570typeDefs = processSchema ( typeDefs )
6671
72+ // eslint-disable-next-line prefer-const
73+ let subscriptionServer
74+
6775let apolloServerOptions = {
6876 typeDefs,
6977 resolvers,
7078 schemaDirectives,
7179 dataSources,
7280tracing :true ,
81+ cache :'bounded' ,
7382cacheControl :true ,
7483engine :! options . integratedEngine ,
7584// Resolvers context from POST
@@ -89,23 +98,15 @@ module.exports = async (options, cb = null) => {
8998return contextData
9099} ,
91100// 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+ }
105107}
106- return contextData
107108}
108- }
109+ } ]
109110}
110111
111112// Automatic mocking
@@ -146,6 +147,36 @@ module.exports = async (options, cb = null) => {
146147
147148// Apollo Server
148149const 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+
149180await server . start ( )
150181
151182// Express middleware
@@ -160,9 +191,7 @@ module.exports = async (options, cb = null) => {
160191} )
161192
162193// Start server
163- const httpServer = http . createServer ( app )
164194httpServer . setTimeout ( options . timeout )
165- server . installSubscriptionHandlers ( httpServer )
166195
167196httpServer . listen ( {
168197host :options . host || 'localhost' ,