Setting Up Your Environment for a Serverless GraphQL API on AWS Lambda

tanjabayer

Tanja Bayer

Posted on May 2, 2023

Setting Up Your Environment for a Serverless GraphQL API on AWS Lambda

Serverless is cool and can save you a lot of money, because you do not have servers running all the time, only when someone wants to use your service - an that is also good for our environment, isn't it? But when you want to start with serverless the amount of documentation might be really overwhelming and you might not know where to start. This blog posts series should help you getting an easy entry into the topic. It will cover the process of constructing a fully serverless GraphQL API, which will include queries, mutations, and subscriptions. The deployment of this API will be accomplished through the use of the AWS CDK.

In this first part we will do the initial setup using the AWS CDK and build an initial version with the AWS Api Gateway and AWS Lambda.

Getting Started

First of all we will be doing everything as code so that it can be reused and easily adapted to future needs. We assume you already have an AWS account and setup your AWS CLI with your credentials. If you did not do this yet, create a account following the AWS User Guide and setup your CLI following the Getting started with the AWS CLI and the user guide on Configuration and credential file settings.

So lets start setting up our project and creating our lambda function with the CDK.

Create a Workspace and your Project

First things first, setup the repo. We will be using nx to create a monorepo to have all our code in one place. Run npx create-nx-workspace@latest serverless-hero --preset=ts and follow the steps and confirm the request to install the necessary packages. Now we have our repo let's setup our package: npm i @nx/node && nx g @nx/node:application serverless-api. When nx asks you which framework to install choose none.

Install the AWS CDK

For being able to use the CDK we first need to install it, for this run npm i -D aws-cdk-lib in the root of your newly created project.

Create the CDK App

For creating our cdk app as an nx package we will use the nx-cdk package. First install the package with npm i -D @nrwl/workspace && npm i -D @cubesoft/nx-cdk and then you can create your cdk app with nx g @cubesoft/nx-cdk:nx-cdk serverless-cdk. This creates a new package called serverless-cdk for us, for finishing the setup we need to provide the correct environment values in the serverless-cdk/src/app.ts file for account and region. And make sure the line in which you put it is uncommented. Then we need to run nx bootstrap serverless-cdk --profile <profile> (the profile parameter is only required if you have multiple profiles in your aws credentials file) and we are ready to go.

Defining the CDK Stack

Now that we have setup everything we can start with the interesting stuff. Let's have a quick look an what we want to achieve.

API Gateway Lambda Connection
So there are two main parts we need to setup:

  1. The API Gateway
  2. The Lambda Function

The API Gateway

Let's start with the fun part, setting up the API Gateway
We will create a HTTP API because this comes at lower costs than the REST API, and we do not need the additional features of the REST API however if you are interested in the differences between both you can read more here.

In the serverless-cdk/src/lib/my-stack.ts you can add the add the HttpApi with the required configurations. Btw. you can also rename the my-stack file and the name of the Stack itself, I renamed it to ServerlessStack, but make sure you correctly reference it in your app.ts file.

import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';

import { CorsHttpMethod, HttpApi } from '@aws-cdk/aws-apigatewayv2-alpha';
export class ServerlessStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const api = new HttpApi(this, 'httpAPI', {
      apiName: `http-api`,
      corsPreflight: {
        allowHeaders: ['Content-Type', 'Authorization'],
        allowMethods: [CorsHttpMethod.GET, CorsHttpMethod.POST],
        allowOrigins: ['*'],
      },
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

Make sure to install the @aws-cdk/aws-apigatewayv2-alpha package.

To ensure that the API can later be called via a browser we need to provide the corsPreflight options, because we also want to also add authorisation functionality later we provide a specific 'Authorization' header, but you can add even more if you need them.

The Lambda Function

Now that we have the Gateway we can create the Lambda function. For this blog post we will create a really simple Lambda Function and we will focus on the GraphQL part in the next blog post.

import { Duration, Size } from 'aws-cdk-lib';
import { Architecture, Code, Function, Runtime } from 'aws-cdk-lib/aws-lambda';
import { RetentionDays } from 'aws-cdk-lib/aws-logs';

const lambda = new Function(this,'api-handler', {
    runtime: Runtime.NODEJS_18_X,
    handler: 'handler',
      code: lambda.Code.fromInline(`
    exports.handler = async function(event) {
      console.log("Hello, CDK!");
      return {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
      };
    }
  `),
    memorySize: Size.gibibytes(1).toMebibytes(),
    architecture: Architecture.ARM_64,
    logRetention: RetentionDays.ONE_MONTH,
    timeout: Duration.seconds(5)
});
Enter fullscreen mode Exit fullscreen mode

This creates the Lambda Function, now we need to connect it with the API Gateway, so that someone can call it. For this you need to install @aws-cdk/aws-apigatewayv2-integrations-alpha

import { HttpApi, HttpMethod } from '@aws-cdk/aws-apigatewayv2-alpha';
import { HttpLambdaIntegration } from '@aws-cdk/aws-apigatewayv2-integrations-alpha';

const readIntegration = new HttpLambdaIntegration('apiReadIntegration', lambda);
const writeIntegration = new HttpLambdaIntegration('apiWriteIntegration', lambda);

api.addRoutes({
   integration: readIntegration,
   methods: [HttpMethod.GET],
   path: '/graphql'
});
api.addRoutes({
   integration: writeIntegration,
   methods: [HttpMethod.POST],
   path: '/graphql'
});
Enter fullscreen mode Exit fullscreen mode

Deploy your stack

Finally, you can deploy your CDK stack using the command nx deploy serverless-cdk. And there you are, you have just created and deployed your first lambda function on AWS. When you visit your AWS Console and go to the AWS API Gateway you can find your invoke url which you can use to check if your deployed api works. Just open it in your browser /graphql and you should see the text "Hello from Lambda!". You made it!

You can find my sample repo here

💖 💪 🙅 🚩
tanjabayer
Tanja Bayer

Posted on May 2, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related