Building a RESTful API on AWS

Creating AWS resources will incur charges if the configurations are not within the free-tier limits. Always check the AWS pricing before creating any AWS resources.

Introduction

In this tutorial, you'll learn how to build an API on AWS using Lambda, API Gateway, OpenAPI, DynamoDB, Cognito, and WAF. Specifically, we'll cover how to set up a serverless API that supports all CRUDL (Create, Read, Update, Delete, List) operations, implement rate limiting, access logging, API keys, and user-owner-based authorization.

By the end of this tutorial, you will have a fully functional API deployed on AWS, and you'll be able to apply these skills to build scalable and secure serverless applications.

Getting Started

What is a RESTful API?

A RESTful API (Representational State Transfer API) is a web service that uses HTTP methods to enable communication between a client and a server. It allows for interaction with web services using standard HTTP methods like GET, POST, PUT, DELETE, and PATCH.

What Services Will We Be Using?

We'll be using the following services in this tutorial:

  • AWS Lambda: A serverless compute service that lets you run code without provisioning or managing servers.
  • Amazon API Gateway: A fully managed service that makes it easy for developers to create, publish, maintain, monitor, and secure APIs.
  • Amazon DynamoDB: A fast and flexible NoSQL database service for all applications that need consistent, single-digit millisecond latency at any scale.
  • Amazon Cognito: A service that provides authentication, authorization, and user management for web and mobile apps.
  • AWS WAF (Web Application Firewall): A web application firewall that helps protect your web applications from common web exploits.

Prerequisites

Before you begin, make sure you have the following:

  • An AWS Account: Sign up for an AWS account if you don't have one.
  • AWS CLI Installed and Configured: Install the AWS CLI and configure it with your AWS credentials.
  • Node.js v18 Installed: Ensure you have Node.js v18 installed on your machine.
  • Basic Knowledge of JavaScript and AWS Services: Familiarity with JavaScript programming and AWS services like Lambda and API Gateway.

Steps

We'll follow these steps to build our API:

  1. Set Up the Development Environment: Configure AWS CLI and set up your project directory.
  2. Create a DynamoDB Table: Set up a DynamoDB table to store data for the API.
  3. Develop Lambda Functions for CRUDL Operations: Write Lambda functions to handle Create, Read, Update, Delete, and List operations.
  4. Define API with OpenAPI Specification: Use OpenAPI to define your API endpoints and methods.
  5. Configure Amazon API Gateway: Set up API Gateway to integrate with Lambda functions and enforce rate limiting and API keys.
  6. Set Up Amazon Cognito for Authorization: Configure Cognito for user authentication and authorization.
  7. Implement AWS WAF for Security: Set up AWS WAF to protect your API from common web exploits.
  8. Deploy and Test the API: Deploy your API and test all endpoints to ensure they work correctly.

Step 1: Set Up the Development Environment

Before diving into coding, we need to set up our development environment to interact with AWS services and manage our project efficiently.

Instructions:

  1. Set Up the Project Directory

    • Create a new directory for your project and navigate into it:

      bash
      Loading...
    • Initialize a new Node.js project:

      bash
      Loading...
  2. Install Necessary Dependencies

    • Install AWS SDK and other required packages:

      bash
      Loading...
    • Note: We use

      uuid
      for generating unique identifiers and
      jsonwebtoken
      for token handling if needed.


Step 2: Create a DynamoDB Table

We'll create a DynamoDB table to store the data that our API will manage.

Instructions:

  1. Create the DynamoDB Table

    • Use the AWS CLI to create a table named

      Items
      with a primary key
      itemId
      :

      bash
      Loading...
    • Verify Table Creation:

      bash
      Loading...
  2. Enable DynamoDB Stream (Optional)

    • If you plan to handle real-time updates, enable DynamoDB Streams:

      bash
      Loading...

Step 3: Develop Lambda Functions for CRUDL Operations

We'll create Lambda functions to perform Create, Read, Update, Delete, and List operations on our DynamoDB table.

Instructions:

  1. Set Up Lambda Function Directory

    • Create a directory for Lambda functions:

      bash
      Loading...
  2. Create the Create Function (

    createItem.js
    )

    • Code:

      javascript
      Loading...
  3. Create the Read Function (

    getItem.js
    )

    • Code:

      javascript
      Loading...
  4. Create the Update Function (

    updateItem.js
    )

    • Code:

      javascript
      Loading...
  5. Create the Delete Function (

    deleteItem.js
    )

    • Code:

      javascript
      Loading...
  6. Create the List Function (

    listItems.js
    )

    • Code:

      javascript
      Loading...
  7. Package and Deploy Lambda Functions

    • Package Functions:

      bash
      Loading...
    • Deploy Functions Using AWS CLI:

      bash
      Loading...
    • Note: Replace

      [YOUR_IAM_ROLE_ARN]
      with the ARN of an IAM role that has the necessary permissions.


Step 4: Define API with OpenAPI Specification

We'll define our API endpoints using the OpenAPI specification to ensure consistency and enable automatic documentation.

Instructions:

  1. Create an OpenAPI YAML File (

    api.yaml
    )

    • Structure:

      yaml
      Loading...
  2. Integrate OpenAPI with API Gateway

    • Use the AWS CLI to import the API definition:

      bash
      Loading...
    • Note: This command will return the

      id
      of the created API.


Step 5: Configure Amazon API Gateway

We'll set up API Gateway to integrate with our Lambda functions, enforce rate limiting, and manage API keys.

Instructions:

  1. Link Lambda Functions to API Endpoints

    • For each endpoint and method, configure API Gateway to use the corresponding Lambda function.

    • Example: Link the

      POST /items
      endpoint to the
      createItem
      Lambda function.

  2. Enable Rate Limiting and Throttling

    • Create a Usage Plan:

      bash
      Loading...
    • Associate API Stages:

      bash
      Loading...
    • Note: Replace

      [API_ID]
      with your API's ID.

  3. Implement API Keys

    • Create an API Key:

      bash
      Loading...
    • Associate API Key with Usage Plan:

      bash
      Loading...
    • Note: Replace

      [USAGE_PLAN_ID]
      and
      [API_KEY_ID]
      with the appropriate IDs.

  4. Enable Access Logging

    • Set Up a CloudWatch Log Group:

      bash
      Loading...
    • Enable Logging on API Gateway Stage:

      bash
      Loading...
    • Note: Replace

      [LOG_GROUP_ARN]
      and
      [LOG_FORMAT]
      accordingly.


Step 6: Set Up Amazon Cognito for Authorization

We'll use Amazon Cognito to manage user authentication and secure our API endpoints.

Instructions:

  1. Create a Cognito User Pool

    • Using AWS CLI:

      bash
      Loading...
    • Note: This will return the

      UserPoolId
      .

  2. Create a Cognito User Pool Client

    • Create User Pool Client:

      bash
      Loading...
    • Note: Replace

      [USER_POOL_ID]
      with your User Pool ID.

  3. Configure API Gateway to Use Cognito Authorizer

    • Create an Authorizer:

      bash
      Loading...
    • Attach Authorizer to API Methods

      • For each method, update the integration to require authorization.
  4. Update Lambda Functions to Extract User Information

    • As seen in the Lambda functions, use
      event.requestContext.authorizer.claims
      to get user details.

Step 7: Implement AWS WAF for Security

We'll protect our API from common web exploits using AWS WAF.

Instructions:

  1. Create a Web ACL

    • Create Web ACL:

      bash
      Loading...
    • Note:

      waf-rules.json
      should define the rules you want to apply.

  2. Associate Web ACL with API Gateway

    • Get the ARN of the API Gateway Stage

      bash
      Loading...
    • Associate Web ACL

      bash
      Loading...
    • Note: Replace

      [WEB_ACL_ARN]
      and
      [API_GATEWAY_STAGE_ARN]
      accordingly.


Step 8: Deploy and Test the API

Now that everything is set up, we'll deploy the API and test all endpoints.

Instructions:

  1. Deploy the API

    • Create Deployment

      bash
      Loading...
  2. Test the Endpoints

    • Create Item

      bash
      Loading...
    • Get Item

      bash
      Loading...
    • Update Item

      bash
      Loading...
    • Delete Item

      bash
      Loading...
    • List Items

      bash
      Loading...
    • Note: Replace

      [API_ID]
      ,
      [REGION]
      ,
      [JWT_TOKEN]
      ,
      [API_KEY]
      , and
      {itemId}
      with actual values.


Conclusion

Congratulations! You've successfully built a secure, serverless API on AWS using Node.js and various AWS services. You now know how to integrate AWS Lambda, API Gateway, DynamoDB, Cognito, and WAF to create a scalable and secure API.

Customizing the Project

You can further enhance this project by:

  • Adding Pagination: Implement pagination in the list endpoint to handle large datasets.
  • Implementing CI/CD: Set up a continuous integration and deployment pipeline using AWS CodePipeline.
  • Enhancing Security: Add additional AWS WAF rules or integrate AWS Shield for DDoS protection.

Next Steps

To continue learning:

  • Explore AWS Services: Delve deeper into AWS services like AWS Step Functions or Amazon SQS.
  • Learn about Serverless Frameworks: Use frameworks like Serverless or AWS SAM to simplify deployment.
  • Study Advanced Security: Implement OAuth 2.0 or integrate with AWS Secrets Manager for credential management.

References

Here's a complete bash script that automates all the steps in this tutorial. Running this script will set up a fully functional RESTful API on AWS.

All Steps as a Script

bash
Loading...

Notes:

  • Before running this script, ensure that:
    • You have the AWS CLI installed and configured with appropriate permissions.
    • You have
      jq
      installed for JSON parsing in bash.
    • You replace any placeholders with your actual values where necessary.
  • The script will create AWS resources that may incur costs. Be sure to clean up resources when they are no longer needed.
  • This script assumes that the AWS CLI is configured with credentials that have the necessary permissions to create IAM roles, Lambda functions, API Gateway APIs, DynamoDB tables, Cognito user pools, and WAF configurations.

Commands and Code Snippets

Here's a summary of the commands and code used throughout this tutorial for your convenience.

bash
Loading...