diff --git a/packages/apollo-server-koa/README.md b/packages/apollo-server-koa/README.md index 0aa826cdaa4..1ba937a892c 100644 --- a/packages/apollo-server-koa/README.md +++ b/packages/apollo-server-koa/README.md @@ -36,6 +36,8 @@ const server = new ApolloServer({ typeDefs, resolvers }); const app = new Koa(); server.applyMiddleware({ app }); +// alternatively you can get a composed middleware from the apollo server +// app.use(server.getMiddleware()); app.listen({ port: 4000 }, () => console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`), diff --git a/packages/apollo-server-koa/src/ApolloServer.ts b/packages/apollo-server-koa/src/ApolloServer.ts index d0d56e55f73..6d6634edc20 100644 --- a/packages/apollo-server-koa/src/ApolloServer.ts +++ b/packages/apollo-server-koa/src/ApolloServer.ts @@ -1,4 +1,4 @@ -import Koa from 'koa'; +import Koa, { Middleware } from 'koa'; import corsMiddleware from '@koa/cors'; import bodyParser from 'koa-bodyparser'; import compose from 'koa-compose'; @@ -19,8 +19,7 @@ import { graphqlKoa } from './koaApollo'; export { GraphQLOptions, GraphQLExtension } from 'apollo-server-core'; import { GraphQLOptions, FileUploadOptions } from 'apollo-server-core'; -export interface ServerRegistration { - app: Koa; +export interface GetMiddlewareOptions { path?: string; cors?: corsMiddleware.Options | boolean; bodyParserConfig?: bodyParser.Options | boolean; @@ -28,6 +27,10 @@ export interface ServerRegistration { disableHealthCheck?: boolean; } +export interface ServerRegistration extends GetMiddlewareOptions { + app: Koa; +} + const fileUploadMiddleware = ( uploadsConfig: FileUploadOptions, server: ApolloServerBase, @@ -80,18 +83,22 @@ export class ApolloServer extends ApolloServerBase { return true; } + public applyMiddleware({ app, ...rest }: ServerRegistration) { + const middleware = this.getMiddleware(rest); + app.use(middleware); + } + // TODO: While Koa is Promise-aware, this API hasn't been historically, even // though other integration's (e.g. Hapi) implementations of this method // are `async`. Therefore, this should become `async` in a major release in // order to align the API with other integrations. - public applyMiddleware({ - app, + public getMiddleware({ path, cors, bodyParserConfig, disableHealthCheck, onHealthCheck, - }: ServerRegistration) { + }: GetMiddlewareOptions): Middleware { if (!path) path = '/graphql'; // Despite the fact that this `applyMiddleware` function is `async` in @@ -107,7 +114,8 @@ export class ApolloServer extends ApolloServerBase { // work has finished. Any errors will be surfaced to Koa through its own // native Promise-catching facilities. const promiseWillStart = this.willStart(); - app.use( + const middlewares = []; + middlewares.push( middlewareFromPath(path, async (_ctx: Koa.Context, next: Function) => { await promiseWillStart; return next(); @@ -115,7 +123,7 @@ export class ApolloServer extends ApolloServerBase { ); if (!disableHealthCheck) { - app.use( + middlewares.push( middlewareFromPath( '/.well-known/apollo/server-health', (ctx: Koa.Context) => { @@ -147,22 +155,22 @@ export class ApolloServer extends ApolloServerBase { this.graphqlPath = path; if (cors === true) { - app.use(middlewareFromPath(path, corsMiddleware())); + middlewares.push(middlewareFromPath(path, corsMiddleware())); } else if (cors !== false) { - app.use(middlewareFromPath(path, corsMiddleware(cors))); + middlewares.push(middlewareFromPath(path, corsMiddleware(cors))); } if (bodyParserConfig === true) { - app.use(middlewareFromPath(path, bodyParser())); + middlewares.push(middlewareFromPath(path, bodyParser())); } else if (bodyParserConfig !== false) { - app.use(middlewareFromPath(path, bodyParser(bodyParserConfig))); + middlewares.push(middlewareFromPath(path, bodyParser(bodyParserConfig))); } if (uploadsMiddleware) { - app.use(middlewareFromPath(path, uploadsMiddleware)); + middlewares.push(middlewareFromPath(path, uploadsMiddleware)); } - app.use( + middlewares.push( middlewareFromPath(path, (ctx: Koa.Context, next: Function) => { if (ctx.request.method === 'OPTIONS') { ctx.status = 204; @@ -199,6 +207,7 @@ export class ApolloServer extends ApolloServerBase { })(ctx, next); }), ); + return compose(middlewares); } }