All of this project’s code can be found in the First Look monorepo on my GitHub.
Introduction
There are a wide range of different options for GraphQL servers with varying deployment methods. Typical methods for hosting your server include virtual machines (AWS EC2, Digital Ocean Droplet) or containers (Cloud Run, AWS ECS). However, if your server does not need to persist state, then you can host it using a serverless function. This includes:
Bundling your application into a zip file
Storing that static file somewhere with blob storage like an S3 bucket
Serving that file using an API gateway and serverless function like an AWS Lambda
Pros and Cons
The benefits include removing large amounts of operations work such as managing the operating system of underlying VMs or creating optimized Dockerfiles. You also no longer need to worry about scaling your application or paying for idle time when your server is not being used.
Since the server state cannot be persisted, the drawbacks include removing the ability to use websockets or subscriptions. The functions will only work for basic GET and POST methods. You also need to write your code with the syntax of the underlying runtime which requires keeping in mind information such as the available Node version and compatible dependencies.
Deployment Providers
This article looks at three different methods of deploying two different GraphQL servers: Apollo Server and GraphQL Yoga. They will be deployed with Netlify Functions, Serverless Framework, and AWS Amplify. All three use the same underlying technology, AWS Lambda functions. They differ in terms of the conventions and abstractions around creating, developing, and deploying those functions.
Netlify Functions
Netlify Functions are scripts that you can write and deploy directly on Netlify. Netlify lets you deploy serverless Lambda functions without an AWS account, and with function management handled directly within Netlify. It requires the least amount of knowledge of AWS, but also gives you the least amount of control over the underlying infrastructure.
Lambda functions can be added to a project by creating a JavaScript file in a configured functions directory. The function endpoint is determined by its filename or the name of its dedicated parent directory. It exports a handler that receives an event object similar to what you would receive from AWS API Gateway.
Serverless Framework
The Serverless Framework is an open source framework for building applications on AWS Lambda. It provides a CLI for developing and deploying AWS Lambda functions, along with the AWS infrastructure resources they require.
The resources and functions are defined in a file called serverless.yml which includes:
The provider for the Node runtime and AWS region
The handler and events for your functions
Once the project is defined in code it can be deployed with the sls deploy command. This command creates a CloudFormation stack defining any necessary resources such as API gateways or S3 buckets.
Amplify
AWS Amplify is a set of tools and services to help frontend web and mobile developers build fullstack applications with AWS infrastructure. It includes a CLI for creating and deploying CloudFormation stacks along with a Console and Admin UI for managing frontend web apps, backend environments, CI/CD, and user data.
Amplify provides open source libraries in various languages including:
The amplify init command creates a boilerplate project that is setup for generating CloudFormation templates. amplify add api configures a Lambda handler and API gateway to serve the function. amplify push uploads the stack templates to an S3 bucket and calls the CloudFormation API to create or update resources in the cloud.
Serve Apollo Server Locally
Apollo Server is an open-source, spec-compliant GraphQL server. Apollo Server Core implements the core logic of Apollo Server.
ApolloServer
apollo-server exports a base version of the ApolloServer constructor which requires two parameters, typeDefs for a schema definition and resolvers for a set of resolvers. The listen method is used to launch the server.
ApolloServer is usually imported either from a batteries-included apollo-server package or from integration packages like apollo-server-lambda.
In Apollo Server 3, apollo-server-lambda is implemented as a wrapper around apollo-server-express and uses serverless-express to parse AWS Lambda events into Express requests. This will cause problems with Netlify Functions, so instead we will install v2.
ApolloServer
Each JavaScript file to be deployed as a synchronous serverless Lambda function must export a handler method. Netlify provides the event and context parameters when the serverless function is invoked.
Run test queries on Apollo Server Lambda Netlify Locally
Open ajcwebdev-apollo-server-netlify.netlify.app/.netlify/functions/index and run the hello query.
Apollo Server Lambda Netlify Final Project Structure
Deploy Apollo Server Lambda with Serverless Framework
ApolloServer
Serverless Framework Configuration
The handler is formatted as <FILENAME>.<HANDLER>. I have included us-west-1 for the region, feel free to enter the AWS region closest to your current location.
Upload to AWS with sls deploy
You can see all of your AWS resources in the various AWS consoles.
CloudFormation
Lambda Function
Lambda Application
API Gateway
Run test queries on Apollo Server Lambda Serverless
Open q6b9hu1h71.execute-api.us-west-1.amazonaws.com/dev/ and run the hello query.
Apollo Server Lambda Serverless Final Project Structure
Deploy Apollo Server Lambda with Amplify
CloudFormation
Create backend with amplify add api
ApolloServer
Upload to AWS with amplify push
Deploy the function containing the GraphQL API.
Lambda Function
Lambda Application
API Gateway
Run test queries on Apollo Server Lambda Amplify
Open kl21tioy61.execute-api.us-east-1.amazonaws.com/dev/graphql and run the hello query.
Apollo Server Lambda Amplify Final Project Structure
Serve GraphQL Yoga Locally
GraphQL Yoga is a fully-featured GraphQL Server with a focus on easy setup and performance. Originally created by Prisma, it is now maintained by Dotan and the Guild. It includes features aimed at providing a great developer experience including file uploading, GraphQL subscriptions support with WebSockets, and TypeScript typing.
If you provide typeDefs and resolvers but omit the schema, graphql-yoga will construct the GraphQLSchema instance using makeExecutableSchema from graphql-tools.