UNPKG

8.18 kBMarkdownView Raw
1[![npm version](https://badge.fury.io/js/apollo-server-lambda.svg)](https://badge.fury.io/js/apollo-server-lambda)
2[![Build Status](https://circleci.com/gh/apollographql/apollo-server/tree/main.svg?style=svg)](https://circleci.com/gh/apollographql/apollo-server)
3[![Join the community forum](https://img.shields.io/badge/join%20the%20community-forum-blueviolet)](https://community.apollographql.com)
4[![Read CHANGELOG](https://img.shields.io/badge/read-changelog-blue)](https://github.com/apollographql/apollo-server/blob/HEAD/CHANGELOG.md)
5
6
7This is the AWS Lambda integration of GraphQL Server. Apollo Server is a community-maintained open-source GraphQL server that works with many Node.js HTTP server frameworks. [Read the docs](https://www.apollographql.com/docs/apollo-server/v2). [Read the CHANGELOG](https://github.com/apollographql/apollo-server/blob/main/CHANGELOG.md).
8
9```shell
10npm install apollo-server-lambda graphql
11```
12
13## Deploying with AWS Serverless Application Model (SAM)
14
15To deploy the AWS Lambda function we must create a Cloudformation Template and a S3 bucket to store the artifact (zip of source code) and template. We will use the [AWS Command Line Interface](https://aws.amazon.com/cli/).
16
17#### 1. Write the API handlers
18
19In a file named `graphql.js`, place the following code:
20
21```js
22const { ApolloServer, gql } = require('apollo-server-lambda');
23const { ApolloServerPluginLandingPageGraphQLPlayground } = require('apollo-server-core');
24
25// Construct a schema, using GraphQL schema language
26const typeDefs = gql`
27 type Query {
28 hello: String
29 }
30`;
31
32// Provide resolver functions for your schema fields
33const resolvers = {
34 Query: {
35 hello: () => 'Hello world!',
36 },
37};
38
39const server = new ApolloServer({
40 typeDefs,
41 resolvers,
42
43 // By default, the GraphQL Playground interface and GraphQL introspection
44 // is disabled in "production" (i.e. when `process.env.NODE_ENV` is `production`).
45 //
46 // If you'd like to have GraphQL Playground and introspection enabled in production,
47 // install the Playground plugin and set the `introspection` option explicitly to `true`.
48 introspection: true,
49 plugins: [ApolloServerPluginLandingPageGraphQLPlayground()],
50});
51
52exports.handler = server.createHandler();
53```
54
55#### 2. Create an S3 bucket
56
57The bucket name must be universally unique.
58
59```bash
60aws s3 mb s3://<bucket name>
61```
62
63#### 3. Create the Template
64
65This will look for a file called graphql.js with the export `graphqlHandler`. It creates one API endpoints:
66
67* `/graphql` (GET and POST)
68
69In a file called `template.yaml`:
70
71```yaml
72AWSTemplateFormatVersion: '2010-09-09'
73Transform: AWS::Serverless-2016-10-31
74Resources:
75 GraphQL:
76 Type: AWS::Serverless::Function
77 Properties:
78 Handler: graphql.handler
79 Runtime: nodejs14.x
80 Events:
81 AnyRequest:
82 Type: Api
83 Properties:
84 Path: /graphql
85 Method: ANY
86```
87
88#### 4. Package source code and dependencies
89
90This will read and transform the template, created in previous step. Package and upload the artifact to the S3 bucket and generate another template for the deployment.
91
92```shell
93aws cloudformation package \
94 --template-file template.yaml \
95 --output-template-file serverless-output.yaml \
96 --s3-bucket <bucket-name>
97```
98
99#### 5. Deploy the API
100
101This will create the Lambda Function and API Gateway for GraphQL. We use the stack-name `prod` to mean production but any stack name can be used.
102
103```
104aws cloudformation deploy \
105 --template-file serverless-output.yaml \
106 --stack-name prod \
107 --capabilities CAPABILITY_IAM
108```
109
110
111## Customizing HTTP serving
112
113`apollo-server-lambda` is built on top of `apollo-server-express`. It combines the HTTP server framework `express` with a package called `@vendia/serverless-express` that translates between Lambda events and Express requests. By default, this is entirely behind the scenes, but you can also provide your own express app with the `expressAppFromMiddleware` option to `createHandler`:
114
115```js
116const { ApolloServer } = require('apollo-server-lambda');
117const express = require('express');
118
119exports.handler = server.createHandler({
120 expressAppFromMiddleware(middleware) {
121 const app = express();
122 app.use(someOtherMiddleware);
123 app.use(middleware);
124 return app;
125 }
126});
127```
128
129## Getting request info
130
131Your ApolloServer's `context` function can read information about the current operation from both the original Lambda data structures and the Express request and response created by `@vendia/serverless-express`. These are provided to your `context` function as `event`, `context`, and `express` options.
132
133The `event` object contains the API Gateway event (HTTP headers, HTTP method, body, path, ...). The `context` object (not to be confused with the `context` function itself!) contains the current Lambda Context (Function Name, Function Version, awsRequestId, time remaining, ...). `express` contains `req` and `res` fields with the Express request and response. The object returned from your `context` function is provided to all of your schema resolvers in the third `context` argument.
134
135```js
136const { ApolloServer, gql } = require('apollo-server-lambda');
137
138// Construct a schema, using GraphQL schema language
139const typeDefs = gql`
140 type Query {
141 hello: String
142 }
143`;
144
145// Provide resolver functions for your schema fields
146const resolvers = {
147 Query: {
148 hello: () => 'Hello world!',
149 },
150};
151
152const server = new ApolloServer({
153 typeDefs,
154 resolvers,
155 context: ({ event, context, express }) => ({
156 headers: event.headers,
157 functionName: context.functionName,
158 event,
159 context,
160 expressRequest: express.req,
161 }),
162});
163
164exports.graphqlHandler = server.createHandler();
165```
166
167## Modifying the Lambda Response (Enable CORS)
168
169To enable CORS the response HTTP headers need to be modified. To accomplish this use the `cors` option.
170
171```js
172const { ApolloServer, gql } = require('apollo-server-lambda');
173
174// Construct a schema, using GraphQL schema language
175const typeDefs = gql`
176 type Query {
177 hello: String
178 }
179`;
180
181// Provide resolver functions for your schema fields
182const resolvers = {
183 Query: {
184 hello: () => 'Hello world!',
185 },
186};
187
188const server = new ApolloServer({
189 typeDefs,
190 resolvers,
191});
192
193exports.handler = server.createHandler({
194 expressGetMiddlewareOptions: {
195 cors: {
196 origin: '*',
197 credentials: true,
198 }
199 },
200});
201```
202
203To enable CORS response for requests with credentials (cookies, http authentication) the allow origin header must equal the request origin and the allow credential header must be set to true.
204
205```js
206const { ApolloServer, gql } = require('apollo-server-lambda');
207
208// Construct a schema, using GraphQL schema language
209const typeDefs = gql`
210 type Query {
211 hello: String
212 }
213`;
214
215// Provide resolver functions for your schema fields
216const resolvers = {
217 Query: {
218 hello: () => 'Hello world!',
219 },
220};
221
222const server = new ApolloServer({
223 typeDefs,
224 resolvers,
225});
226
227exports.handler = server.createHandler({
228 expressGetMiddlewareOptions: {
229 cors: {
230 origin: true,
231 credentials: true,
232 }
233 },
234});
235```
236
237### Cors Options
238
239The options correspond to the [express cors configuration](https://github.com/expressjs/cors#configuration-options) with the following fields(all are optional):
240
241* `origin`: boolean | string | string[]
242* `methods`: string | string[]
243* `allowedHeaders`: string | string[]
244* `exposedHeaders`: string | string[]
245* `credentials`: boolean
246* `maxAge`: number
247
248## Principles
249
250GraphQL Server is built with the following principles in mind:
251
252* **By the community, for the community**: GraphQL Server's development is driven by the needs of developers
253* **Simplicity**: by keeping things simple, GraphQL Server is easier to use, easier to contribute to, and more secure
254* **Performance**: GraphQL Server is well-tested and production-ready - no modifications needed
255
256Anyone is welcome to contribute to GraphQL Server, just read [CONTRIBUTING.md](https://github.com/apollographql/apollo-server/blob/main/CONTRIBUTING.md), take a look at the [roadmap](https://github.com/apollographql/apollo-server/blob/main/ROADMAP.md) and make your first PR!