Building a Serverless API with AWS API Gateway AWS Lambda and DynamoDB

Published On: January 26, 2025Categories: Cloud5.2 min read

Serverless computing has revolutionized the way developers build and deploy applications by removing the need to manage server infrastructure. AWS offers powerful tools such as AWS API Gateway and AWS Lambda to create robust serverless APIs. This blog will guide you through the process of building a serverless API step by step.

What is a Serverless API?

A serverless API enables you to expose functionality over HTTP/S endpoints without provisioning or managing servers. AWS Lambda executes backend logic in response to API calls, while AWS API Gateway acts as a front-door for API traffic.

Why Use AWS API Gateway and AWS Lambda?

  1. Scalability: Automatically scales with traffic.
  2. Cost-Effectiveness: Pay only for what you use.
  3. Ease of Use: AWS provides a streamlined setup for API creation.
  4. Integration: Easily connects to other AWS services.

Overview

Here’s how the system will work:

  1. API Gateway will manage the HTTP requests and route them to the appropriate Lambda functions.
  2. Lambda Functions will handle the business logic:
    • A POST function to create new records in DynamoDB.
    • A GET function to fetch all records from DynamoDB.
  3. DynamoDB will store the application data.

This architecture eliminates the need for server management, allowing you to focus on your API logic.

Prerequisites

Before starting, ensure the following:

  1. An AWS account.
  2. AWS CLI installed and configured (aws configure).
  3. Basic knowledge of AWS Lambda, API Gateway, and DynamoDB.

Step 1: Create a DynamoDB Table

First, we’ll create a DynamoDB table to store our API data.

Run the following AWS CLI command to create a table named Users with a primary key userId:

aws dynamodb create-table \

  –table-name Users \

  –attribute-definitions AttributeName=userId,AttributeType=S \

  –key-schema AttributeName=userId,KeyType=HASH \

  –provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5

This will create a table with userId as the partition key.

Step 2: Write Lambda Functions

We’ll create two Lambda functions—one for handling GET requests and another for POST requests.

1. GET Lambda Function

This function retrieves all records from the Users table.

Save the following code as get_users.py:

import boto3

import json

dynamodb = boto3.resource(‘dynamodb’)

table = dynamodb.Table(‘Users’)

def handler(event, context):

    try:

        response = table.scan()

        return {

            ‘statusCode’: 200,

            ‘body’: json.dumps(response[‘Items’])

        }

    except Exception as e:

        return {

            ‘statusCode’: 500,

            ‘body’: json.dumps({‘error’: str(e)})

        }

}

2. POST Lambda Function

This function inserts a new record into the Users table.

Save the following code as post_users.py

import boto3

import json

import uuid

dynamodb = boto3.resource(‘dynamodb’)

table = dynamodb.Table(‘Users’)

def handler(event, context):

    try:

        body = json.loads(event[‘body’])

        user = {

            ‘userId’: str(uuid.uuid4()),

            ‘name’: body[‘name’],

            ’email’: body[’email’]

        }

        table.put_item(Item=user)

        return {

            ‘statusCode’: 201,

            ‘body’: json.dumps({‘message’: ‘User created’, ‘user’: user})

        }

    except Exception as e:

        return {

            ‘statusCode’: 500,

            ‘body’: json.dumps({‘error’: str(e)})

        }

}

Step 3: Deploy Lambda Functions

1. Create ZIP Packages

Compress the Lambda code into ZIP files:

zip get_users.zip get_users.py

zip post_users.zip post_users.py

2. Deploy Lambda Functions

Deploy the functions using the AWS CLI:

# GET Lambda

aws lambda create-function –function-name GetUsersFunction \

  –runtime python3.9 \

  –role arn:aws:iam::<Your-Account-ID>:role/<Your-Lambda-Execution-Role> \

  –handler get_users.handler \

  –zip-file fileb://get_users.zip

# POST Lambda

aws lambda create-function –function-name PostUsersFunction \

  –runtime python3.9 \

  –role arn:aws:iam::<Your-Account-ID>:role/<Your-Lambda-Execution-Role> \

  –handler post_users.handler \

  –zip-file fileb://post_users.zip

Step 4: Configure API Gateway

1. Create an API

Create a new REST API:

aws apigateway create-rest-api –name “ServerlessAPI”

Note the restApiId from the output.

2. Create Resources

Add a resource /users:

aws apigateway create-resource –rest-api-id <restApiId> \

  –parent-id <rootResourceId> \

  –path-part users

Note the resourceId from the output.

3. Add Methods

  • POST Method:

aws apigateway put-method –rest-api-id <restApiId> \

  –resource-id <resourceId> \

  –http-method POST \

  –authorization-type NONE

Integrate the POST method with the PostUsersFunction Lambda:

aws apigateway put-integration –rest-api-id <restApiId> \

  –resource-id <resourceId> \

  –http-method POST \

  –type AWS_PROXY \

  –integration-http-method POST \

  –uri arn:aws:apigateway:<Region>:lambda:path/2015-03-31/functions/arn:aws:lambda:<Region>:<Account-ID>:function:PostUsersFunction/invocations

 

  • GET Method:

aws apigateway put-method –rest-api-id <restApiId> \

  –resource-id <resourceId> \

  –http-method GET \

  –authorization-type NONE

Integrate the GET method with the GetUsersFunction Lambda:

aws apigateway put-integration –rest-api-id <restApiId> \

  –resource-id <resourceId> \

  –http-method GET \

  –type AWS_PROXY \

  –integration-http-method POST \

  –uri arn:aws:apigateway:<Region>:lambda:path/2015-03-31/functions/arn:aws:lambda:<Region>:<Account-ID>:function:GetUsersFunction/invocations


Step 5: Deploy the API

Deploy the API to a stage:

aws apigateway create-deployment –rest-api-id <restApiId> \

  –stage-name dev

Step 6: Grant API Gateway Permissions

Grant API Gateway permission to invoke the Lambda functions:

aws lambda add-permission –function-name PostUsersFunction \

  –statement-id api-gateway-post-permission \

  –action lambda:InvokeFunction \

  –principal apigateway.amazonaws.com \

  –source-arn arn:aws:execute-api:<Region>:<Account-ID>:<restApiId>/*/POST/users

aws lambda add-permission –function-name GetUsersFunction \

  –statement-id api-gateway-get-permission \

  –action lambda:InvokeFunction \

  –principal apigateway.amazonaws.com \

  –source-arn arn:aws:execute-api:<Region>:<Account-ID>:<restApiId>/*/GET/users

Step 7: Test the API

Use curl or Postman to test the API:

  • POST Request:

curl -X POST <ApiEndpoint>/users -H “Content-Type: application/json” \

  -d ‘{“name”: “Neo  Lee”, “email”: “neo@rambunct.com”}’

 

curl -X POST https://xkzutl6uqh.execute-api.us-east-1.amazonaws.com/dev/users \

  -H “Content-Type: application/json” \

  -d ‘{“name”: “Neo Lee”, “email”: “neo@rambunct.com”}’

  • GET Request:

curl <ApiEndpoint>/users

Conclusion

In this tutorial, we built a serverless REST API using AWS Lambda, API Gateway, and DynamoDB. This architecture enables seamless scaling and minimal maintenance, making it perfect for cloud-native applications. You can extend this API by adding authentication, custom domains, or additional endpoints. Serverless is the future—dive in and explore!