Steven Develops Icon

Steven Develops

All things engineering

Opinions are my own

BlogPortfolioContactX TwitterLinkedInGitHub

Part 1: Deploying an Apollo GraphQL Odyssey Server with AWS Lambda

Published onin Software Engineeringby

Connecting to Apollo Studio
Connecting to Apollo Studio

As I approached the finale of my Apollo Odyssey GraphQL journey, my adventure took an unexpected turn. Due to a recent event involving Heroku and GitHub tokens, Heroku has revoked all OAuth tokens and disabled the feature for the foreseeable future. This hiccup presented itself as an opportunity for me to challenge myself and test my newly acquired Amazon Web Service skills.After some research, I choose to use AWS Lambda to deploy our GraphQL server and AWS Amplify to deploy our React application. There are other ways to get our application online (I believe you can do it with just AWS Amplify), but these tools provided the simplest and most streamline process. This post is to serve as a walk through for finishing our Space Odyssey adventure using AWS instead of Heroku. Part 1 covers deploying the backend server with AWS Lambda and Part 2 covers deploying our React Application to AWS Amplify, putting our FULL Stack Application into action!

Prerequisites

npm install apollo-server-lambda 

Next, we will create a file that must be named ‘graphql.js’ in the root of our server project (not in the src folder!) This file will be used for configuring later. Copy and paste the following into your graphql.js file.

Setting up Apollo Server Lambda

In this tutorial, we’ll be deploying our GraphQL server to AWS Lambda. To start, navigate to your odyssey-lift-off-part5-server’s root folder and install the apollo-server-lambda package

npm install apollo-server-lambda

Next, we will create a file that must be named ‘graphql.js’ in the root of our server project (not in the src folder!) This file will be used for configuring our server later. Copy and paste the following into your graphql.js file.

// graphql.js
const { ApolloServer } = require('apollo-server-lambda');

const server = new ApolloServer();

exports.graphqlHandler = server.createHandler();

Note that the ApolloServer is being imported from the apollo-server-lambda package we just installed. Also notice that the last line exports a named graphqlHandler with a Lambda function handler!

Before we put it all together, there is one more key change we need to make. In our src/schema.js file, we import from the apollo-server-lambda package instead of the apollo-server package. This requires us to change

// src/schema.js
const { gql } = require('apollo-server'); 

to

// src/schema.js
const { gql } = require('apollo-server-lambda');

Now let’s connect the rest of our app.

In our newly created graphql.js file, let’s import our Type Definitions that we previously defined in our schema, our datasources (our TrackAPI), and our resolvers.

// graphql.js

const { ApolloServer } = require('apollo-server-lambda');
const typeDefs = require('./src/schema')
const TrackAPI = require('./src/datasources/track-api');
const resolvers = require('./src/resolvers')

Now we are ready to plug these variables into our ApolloServer instance.

// graphql.js

// ...

const server = new ApolloServer({
  typeDefs,
  resolvers,
  dataSources: () => {
    return {
      trackAPI: new TrackAPI(),
    };
  },
});

Our completed

grapqhl.js file should look like this:

// graphql.js

const { ApolloServer } = require('apollo-server-lambda');
const resolvers = require('./src/resolvers');
const TrackAPI = require('./src/datasources/track-api');
const typeDefs = require('./src/schema');

const server = new ApolloServer({
  typeDefs,
  resolvers,
  dataSources: () => {
    return {
      trackAPI: new TrackAPI(),
    };
  },
});

exports.graphqlHandler = server.createHandler();

Deploying with the Serverless Framework

Serverless is a framework that makes deploying to services like AWS Lambda simpler.

To do this, we need to create a config file named ‘serverless.yml’ in our root directory to determine what service to deploy to and where the handlers are.

To avoid getting to far into the weeds, the following file can be copied and pasted into the root of your project.

# serverless.yml

service: apollo-lambda
provider:
  name: aws
  runtime: nodejs14.x
functions:
  graphql:
    # this is formatted as <FILENAME>.<HANDLER>
    handler: graphql.graphqlHandler
    events:
    - http:
        path: /
        method: post
        cors: true
    - http:
        path: /
        method: get
        cors: true

After you have created this file in your server’s root directory, you are ready to deploy. Run the following command

serverless deploy

This command may take a few minutes to finish. This command builds the functions, zips up the artifacts, and uploads the artifacts to a new S3 bucket. Then it creates a CloudFormation Stack, connecting our new Lambda function with those artifacts and, if successful, outputs the HTTP endpoint URLs to the console. You can view the created S3 bucket and Lambda function and CloudFormation on your AWS account.

(Note that you will see a new .serverless directory in your project folder with the apollo-lambda.zip file as well as some json files).

If all went well, we should receive a message such as ‘✔ Service deployed to stack apollo-lambda-dev’ as well as our endpoints and functions (graphql).

Connecting our Apollo GraphQL to our new Server

For our final server step, we need to input the Apollo Server variables we received when we registered our schema. To do this, let’s log into our browser based AWS console and navigate to our Lambda Services (there is a search bar next to the Services tab where you can quick search Lambda).

Locate our Lambda function which should be prefixed by apollo-lambda and click on it.

We should now see our function overview. In the navigation below the function overview, locate configuration and click on it. Navigate to ‘Environment Variables’ and press the Edit button that appears. Carefully add your environment variables one at a time ensuring you capture everything to the left of the equal sign for the Enviroment Key, and everything to the right of the equal sign for the Enviroment Key Value. Once you have all 3 environment variables added, go ahead and press save to save your changes.

Connect to our GraphQL Server

With our environment variables added, let’s go ahead and visit our new GraphQL Server! Using the endpoint that was posted to our terminal, connect to your GraphQL Server. If all went well, you should be welcomed with the following screen

Finishing up with our Server

We have now successfully deployed our Apollo GraphQL Server to AWS Lambda. If you are not immediately moving on with deploying our frontend, it is always good practice to delete your AWS services to avoid any unexpected costs.

Run the following command to remove everything that we created from your AWS account (including the Cloudformation, S3 Bucket, and Lambda Function).

Please note, that if you intend on carrying on with our deployment, you should not run the following command until you have completed the project and are satisfied with the results.

npx serverless remove

Next up, deploying our React App to AWS Amplify

You are now cleared to complete your Castronaut mission in Deploying your Apollo Server! Finish out the lesson noting the differences in deploying to Heroku vs deploying to AWS Lambda. For example, one difference is that we do not need to set the PORT to deploy our server!

When your mission is complete, carry on to our next mission, Deploying Apollo Client, and check out my article on Part 2: Deploying Apollo Client to AWS Amplify.

If you found this article helpful, feel free to reach out to me on Twitter. Thanks for reading!

References

Deploying with AWS Lambda, How to deploy Apollo Server with AWS Lambda

https://www.apollographql.com/docs/apollo-server/deployment/lambda/

Steven Brown in Milan
Steven Brown

Let's Connect

If you've journeyed this deep into my site, you're exactly who I want to connect with—whether it's about a fresh project or just a friendly chat. Feel free to reach out through social media or my contact page!

Copyright © 2024 Steven Develops. All Rights Reserved.