-
Notifications
You must be signed in to change notification settings - Fork 2k
/
ApolloServer.ts
79 lines (74 loc) · 2.5 KB
/
ApolloServer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import type { Handler } from 'aws-lambda';
import {
ApolloServer as ApolloServerExpress,
ExpressContext,
GetMiddlewareOptions,
} from 'apollo-server-express';
import type { GraphQLOptions } from 'apollo-server-core';
import express from 'express';
import serverlessExpress, {
getCurrentInvoke,
} from '@vendia/serverless-express';
export interface CreateHandlerOptions {
expressAppFromMiddleware?: (
middleware: express.RequestHandler,
) => express.Application;
expressGetMiddlewareOptions?: GetMiddlewareOptions;
}
export interface LambdaContextFunctionParams {
event: ReturnType<typeof getCurrentInvoke>['event'];
context: ReturnType<typeof getCurrentInvoke>['context'];
express: ExpressContext;
}
function defaultExpressAppFromMiddleware(
middleware: express.RequestHandler,
): express.Application {
const app = express();
app.use(middleware);
return app;
}
export class ApolloServer extends ApolloServerExpress<LambdaContextFunctionParams> {
protected override serverlessFramework(): boolean {
return true;
}
public createHandler<TEvent = any, TResult = any>(
options?: CreateHandlerOptions,
): Handler<TEvent, TResult> {
let realHandler: Handler<TEvent, TResult>;
return async (...args) => {
await this.ensureStarted();
if (!realHandler) {
const middleware = this.getMiddleware(
// By default, serverless integrations serve on root rather than
// /graphql, since serverless handlers tend to just do one thing and
// paths are generally configured as part of deploying the app.
{
path: '/',
...options?.expressGetMiddlewareOptions,
},
);
const app = (
options?.expressAppFromMiddleware ?? defaultExpressAppFromMiddleware
)(middleware);
realHandler = serverlessExpress({ app });
}
return (await realHandler(...args)) as TResult;
};
}
// This method is called by apollo-server-express with the request and
// response. It fetches the Lambda context as well (from a global variable,
// which is safe because the Lambda runtime doesn't invoke multiple operations
// concurrently).
override async createGraphQLServerOptions(
req: express.Request,
res: express.Response,
): Promise<GraphQLOptions> {
const { event, context } = getCurrentInvoke();
const contextParams: LambdaContextFunctionParams = {
event,
context,
express: { req, res },
};
return super.graphQLServerOptions(contextParams);
}
}