UNPKG

2.37 kBPlain TextView Raw
1import lambda from 'aws-lambda';
2import {
3 GraphQLOptions,
4 HttpQueryError,
5 runHttpQuery,
6} from 'apollo-server-core';
7import { Headers } from 'apollo-server-env';
8import { ValueOrPromise } from 'apollo-server-types';
9
10export interface LambdaGraphQLOptionsFunction {
11 (event: lambda.APIGatewayProxyEvent, context: lambda.Context): ValueOrPromise<
12 GraphQLOptions
13 >;
14}
15
16export function graphqlLambda(
17 options: GraphQLOptions | LambdaGraphQLOptionsFunction,
18): lambda.APIGatewayProxyHandler {
19 if (!options) {
20 throw new Error('Apollo Server requires options.');
21 }
22
23 if (arguments.length > 1) {
24 throw new Error(
25 `Apollo Server expects exactly one argument, got ${arguments.length}`,
26 );
27 }
28
29 const graphqlHandler: lambda.APIGatewayProxyHandler = (
30 event,
31 context,
32 callback,
33 ): void => {
34 context.callbackWaitsForEmptyEventLoop = false;
35 let { body, isBase64Encoded } = event;
36
37 if (body && isBase64Encoded) {
38 body = Buffer.from(body, 'base64').toString();
39 }
40
41 if (event.httpMethod === 'POST' && !body) {
42 return callback(null, {
43 body: 'POST body missing.',
44 statusCode: 500,
45 });
46 }
47
48 const contentType = event.headers["content-type"] || event.headers["Content-Type"];
49 let query: Record<string, any> | Record<string, any>[];
50
51 if (body && event.httpMethod === 'POST' &&
52 contentType && contentType.startsWith("multipart/form-data")
53 ) {
54 query = body as any;
55 } else if (body && event.httpMethod === 'POST') {
56 query = JSON.parse(body);
57 } else {
58 query = event.queryStringParameters || {};
59 }
60
61 runHttpQuery([event, context], {
62 method: event.httpMethod,
63 options: options,
64 query,
65 request: {
66 url: event.path,
67 method: event.httpMethod,
68 headers: new Headers(event.headers),
69 },
70 }).then(
71 ({ graphqlResponse, responseInit }) => {
72 callback(null, {
73 body: graphqlResponse,
74 statusCode: 200,
75 headers: responseInit.headers,
76 });
77 },
78 (error: HttpQueryError) => {
79 if ('HttpQueryError' !== error.name) return callback(error);
80 callback(null, {
81 body: error.message,
82 statusCode: error.statusCode,
83 headers: error.headers,
84 });
85 },
86 );
87 };
88
89 return graphqlHandler;
90}