Deploying a Lambda-Backed REST API Using AWS CDK: A Detailed Guide

Explore the step-by-step process of deploying a lambda backed API using AWS CDK in this detailed guide. From setting up your environment to implementing and testing the API, this blog post covers it all. Ideal for both beginners and experienced developers, this guide offers practical examples and clear explanations to help you manage complex cloud infrastructure effectively. Dive in to enhance your understanding of AWS CDK and learn how to deploy a functional web API.

Step 1: Setting Up Your Environment

Before you can start using AWS CDK, ensure you have Node.js, AWS CLI, and AWS CDK Toolkit installed. Configure your AWS credentials using the AWS CLI.. Here’s a more detailed breakdown:

  • Install Node.js: AWS CDK requires Node.js, which is a JavaScript runtime that lets you run JavaScript code on your computer. You can download Node.js from the official website. AWS CDK requires Node.js version 10.x or later. After installing, you can verify the installation by running node --version in your terminal or command prompt.

  • Install AWS CLI: The AWS Command Line Interface (CLI) is a tool that allows you to interact with AWS services from your terminal or command prompt. You can download AWS CLI from the official AWS website. After installing, you can verify the installation by running aws --version.

  • Configure AWS CLI: After installing AWS CLI, you need to configure it with your AWS credentials. You can do this by running aws configure and then entering your Access Key ID, Secret Access Key, Default Region Name, and Default Output Format when prompted. These credentials are associated with your AWS account and are used to authenticate your requests.
  • Install AWS CDK Toolkit: The AWS CDK Toolkit, also known as AWS CDK Command Line Interface (CLI), is a command-line tool that allows you to work with AWS CDK apps. You can install it by running npm install -g aws-cdk in your terminal or command prompt. The -g option installs the toolkit globally, making it available to all your projects. After installing, you can verify the installation by running cdk --version.

Once you’ve completed these steps, your environment is set up and ready for AWS CDK development. Remember to keep your software up to date, as new versions often come with important features, improvements, and bug fixes.

Step 2: Creating a New CDK Project

Create a new CDK project using the cdk init command. For this example, we'll use TypeScript:

cdk init app --language typescript

Your output should look like this.

After the execution is finished, you’ll notice that your project directory is populated with several new directories and files. These files form the basic structure of your CDK application. To give you a clearer picture, here’s what your filesystem should look like:

Step 3: Defining the Infrastructure

We’ll be creating a simple hit counter API. For that, we'll need an Amazon API Gateway to handle requests, an AWS Lambda function to process these requests and increment the hit counter, and an Amazon DynamoDB table to store the hit count. Start by navigating to the lib directory of your CDK project. This is where you’ll define your infrastructure.

Within the lib directory, create a new directory called lambda at the root level and, within this directory, create a file named hitcounter.js. This directory and file will serve as the storage location and the codebase respectively for our backing lambda function.

const { DynamoDB } = require("aws-sdk");

exports.handler = async function (event) {
  console.log("request:", JSON.stringify(event, undefined, 2));

  try {
    // create AWS SDK clients
    const dynamo = new DynamoDB();

    // update dynamo entry for "path" with hits++
    const response = await dynamo
      .updateItem({
        TableName: process.env.HITS_TABLE_NAME,
        Key: { path: { S: event.path } },
        UpdateExpression: "ADD hits :incr",
        ExpressionAttributeValues: { ":incr": { N: "1" } },
        ReturnValues: "UPDATED_NEW",
      })
      .promise();

    const hits = Number(response.Attributes.hits.N);

    return {
      statusCode: 200,
      body: `This page has been viewed ${hits} times!`,
    };
  } catch (error) {
    console.error("Error:", error);
    return {
      statusCode: 500,
      body: "An error occurred. Please try again later.",
    };
  }
};

Now, it’s time to create a Construct that will wire everything together. Back in the lib directory, create a file named hitcounter.ts. This file will define the Construct.

import { Construct } from "constructs";
import { aws_apigateway as apigw, StackProps } from "aws-cdk-lib";
import { aws_dynamodb as dynamo } from "aws-cdk-lib";
import { aws_lambda as _lambda } from "aws-cdk-lib";

export class HitCounter extends Construct {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id);

    const table = new dynamo.Table(this, "Hits", {
      partitionKey: { name: "path", type: dynamo.AttributeType.STRING },
    });

    const func = new _lambda.Function(this, "HitCounterHandler", {
      runtime: _lambda.Runtime.NODEJS_14_X,
      handler: "hitcounter.handler",
      code: _lambda.Code.fromAsset("lambda"),
      environment: {
        HITS_TABLE_NAME: table.tableName,
      },
    });

    // grant the lambda role read/write permissions to our table
    table.grantReadWriteData(func);

    // defines an API Gateway REST API resource backed by our lambda function.
    new apigw.LambdaRestApi(this, "Endpoint", {
      handler: func,
    });
  }
}

Lastly, we need to instantiate our Construct within a Stack to make it deployable. To do this, open the file lib/demo-project-stack.ts and add the necessary code to create an instance of the Construct.

import * as cdk from "aws-cdk-lib";
import { HitCounter } from "./hitcounter";

export class DemoProjectStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    new HitCounter(this, "HelloHitCounter", {});
  }
}

Step 4: Deploying the Infrastructure

At this stage, we’re ready to deploy. Deploy the infrastructure using the cdk deploy command. This will create a CloudFormation stack with your API Gateway, Lambda function, and DynamoDB table.

Here’s what happens in the backend when you run cdk deploy:

  1. CloudFormation Template Synthesis: AWS CDK first takes your app and compiles it into a CloudFormation template. This template is a JSON or YAML file that describes all the AWS resources your app is composed of.
  2. CloudFormation Stack Creation: AWS CDK then takes this CloudFormation template and deploys it as a CloudFormation stack. A stack is a collection of AWS resources that you can manage as a single unit. In other words, all the resources in a stack are created, updated, or deleted together.
  3. Resource Provisioning: AWS CloudFormation then looks at the template and provisions all the resources described in it. This includes creating AWS Lambda functions, setting up API Gateways, creating DynamoDB tables, and more.
  4. Stack Outputs: After the stack is successfully created, AWS CDK will display any outputs specified in your CDK app. Outputs are a way to export information about the resources in your stack, such as a URL for an API Gateway or the name of a DynamoDB table.

Step 5: Testing the Hit Counter API

You can test your hit counter API by making a GET request to the API Gateway URL. Each time you make a request, the hit counter should increment and the new count should be displayed and stored in the DynamoDB table.

Step 6: Cleaning Up

After you’ve finished with your project, it’s crucial to clean up and remove the resources you’ve deployed. This can be done by executing the cdk destroy command. This command will delete the CloudFormation stack, effectively removing all the resources that were provisioned as part of the stack.

It’s important to note that if you neglect this cleanup step, AWS may continue to charge you for the resources that are still running. Therefore, to avoid any unnecessary costs, always remember to destroy your resources once you’re done using them.

Conclusion

By following these steps, you can deploy a hit counter API using AWS CDK. This API increments a hit counter every time it’s accessed, displays the latest count, and stores this data in a DynamoDB table. This example demonstrates the power and flexibility of AWS CDK, and how it can be used to manage complex cloud infrastructure.

Resources:

Enjoyed this article?

Share it with your network to help others discover it

Continue Learning

Discover more articles on similar topics