Serverless environments such as AWS Lambda allows you to run your server-side code without obtaining/maintaining/paying a dedicated server. You don’t have to care about OS/software updates and you can focus on your application code. Also, you pay as you go!
In this article we will see how to run a GraphQL server on AWS Lambda step by step.
We are going to use:
- NodeJS
- Lambda & API Gateway
- AWS cli
- CloudFormation
- S3 bucket
Setup the NodeJs project
At the time of this writing, the latest NodeJs version that is supported in the AWS Lambda environment is nodejs12.x
. So, make sure that you have installed a v12.X
version in your system. We will use nvm for this.
1~ $ nvm install v12.7.0
2~ $ nvm use v12.7.0
The Lambda function
We will use the NodeJS library apollo-server-lambda which is the AWS Lambda integration of GraphQL Server.
1~ $ npm init
2~ $ npm i apollo-server-lambda
graphql.js
1const { ApolloServer: ApolloServerLambda, gql } = require('apollo-server-lambda');
2
3const typeDefs = gql`
4 type User {
5 id: ID
6 name: String
7 }
8 type Query {
9 me: User
10 }
11 type Mutation {
12 log(message: String): String
13 }
14`;
15
16const resolvers = {
17 Query: {
18 me: () => {
19 return { id: 1, name: 'John' };
20 }
21 },
22 Mutation: {
23 log: (parent, args) => {
24 const { message } = args;
25 const info = `logging: ${message}`;
26 console.log(info);
27 return info;
28 }
29 }
30};
31
32const server = new ApolloServerLambda({
33 typeDefs,
34 resolvers,
35 context: ({ event, context }) => ({
36 functionName: context.functionName,
37 headers: event.headers
38 }),
39 playground: {
40 endpoint: '/Prod/graphql'
41 },
42 introspection: true
43});
44
45exports.handler = server.createHandler({
46 cors: {
47 origin: '*',
48 credentials: true
49 }
50});
CloudFormation
CloudFormation allows you to define AWS resources in code. In the following template we define a Lambda function and an API Gateway by using the AWS::Serverless::Function
resource type:
template.yml
1AWSTemplateFormatVersion: '2010-09-09'
2Transform: AWS::Serverless-2016-10-31
3Globals:
4 Function:
5 Timeout: 6
6
7Resources:
8 GraphQLFunction:
9 Type: AWS::Serverless::Function
10 Properties:
11 CodeUri: .
12 Handler: graphql.handler
13 Runtime: nodejs12.x
14 Events:
15 GraphQL:
16 Type: Api
17 Properties:
18 Path: /graphql
19 Method: any
20 Environment:
21 Variables:
22 NODE_ENV: production
23
24Outputs:
25 # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
26 GraphQLApi:
27 Description: "API Gateway endpoint URL for Prod stage for GraphQL lambda function"
28 Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/graphql"
29 Export:
30 Name: GraphQLApi
AWS cli
In the next steps we will use the AWS cli to deploy our app. Make sure that you have configured the AWS cli first by running aws configure.
S3 Bucket
We need to create a S3 bucket to host the code of the Lambda function. Replace {your-bucket-name}
with a universal unique S3 bucket name of your choice.
1~ $ aws s3 mb s3://{your-bucket-name} --region eu-central-1
Package your code
The below command zips & uploads your code in your S3 bucket. Also, it exports the template-output.yml
file which will be used in the next step.
1~ $ aws cloudformation package \
2 --template-file template.yml \
3 --output-template-file template-output.yml \
4 --s3-bucket {your-bucket-name}
Deploy your code
The following command will deploy our code to our Lambda function. You can replace the serverless-graphql
with your CloudFormation stack name of your choice.
1~ $ aws cloudformation deploy \
2 --template-file template-output.yml \
3 --stack-name serverless-graphql \
4 --capabilities CAPABILITY_IAM \
5 --no-fail-on-empty-changeset
6
7waiting for changeset to be created..
8Waiting for stack create/update to complete
9
10Successfully created/updated stack - serverless-graphql
Export the URL of the GraphQL server
The final step is to get the exported GraphQL URL:
1~ $ aws cloudformation list-exports \
2 --query "Exports[?Name=='GraphQLApi'].Value"
3
4[
5 "https://k6hl3sdw0b.execute-api.eu-central-1.amazonaws.com/Prod/graphql"
6]
We are live!
We are live at 🚀 https://k6hl3sdw0b.execute-api.eu-central-1.amazonaws.com/Prod/graphql 🚀.
At this link we can play with the GraphQL Playground which is a graphical, interactive, in-browser GraphQL IDE that allows you to explore/test visually the avaialble GraphQL queries, mutations and subcriptions.
Also, let’s test it from the command line:
1$ curl \
2 -X POST \
3 -H "Content-Type: application/json" \
4 --data '{ "query": "{ me { id name } } "}' \
5 https://k6hl3sdw0b.execute-api.eu-central-1.amazonaws.com/Prod/graphql
6
7{"data":{"me":{"id":"1","name":"John"}}}
Nice! It works as expected!
The complete code of this post is at my Github repo!
For more tech posts follow me on Twitter at @johndusaitis!
Thanks for reading!