AWS Builder Center

Building Your First Serverless REST API with AWS Lambda, API Gateway, and DynamoDB

A step-by-step guide to deploying a scalable, cost-efficient serverless backend on AWS without managing a single server.

Student Builder | Aspiring Data Scientist & Cloud Practitioner

Overview

Modern cloud architectures prioritize speed, scalability, and operational simplicity. Instead of provisioning virtual machines or managing container clusters for simple workloads, serverless architecture lets you run code on demand with automatic scaling and zero idle costs.
In this walkthrough, we will construct a lightweight, persistent REST API using:
  • Amazon API Gateway to route HTTP requests.
  • AWS Lambda (Python 3.12) to execute business logic.
  • Amazon DynamoDB as a fast, fully managed NoSQL data store.

Architecture Flow

  1. A client issues an HTTP request (GET or POST) to an Amazon API Gateway HTTP API endpoint.
  2. API Gateway validates the request and invokes an AWS Lambda function.
  3. The Lambda function handles the request logic, interacts with Amazon DynamoDB, and formats a response.
  4. API Gateway sends the JSON payload back to the client.

Step 1: Create the DynamoDB Table

  1. Open the Amazon DynamoDB console.
  2. Select Create table.
  3. Configure the table:
  • Table name: ItemsTable
  • Partition key: itemId (Type: String)
  1. Keep the default table settings and choose Create table.

Step 2: Create the IAM Role for Lambda

Your Lambda function requires read and write permissions to interact with DynamoDB.
  1. Navigate to the IAM Console > Roles > Create role.
  2. Select AWS service as the trusted entity and pick Lambda.
  3. Attach the following managed policies:
  • AWSLambdaBasicExecutionRole (for Amazon CloudWatch logging)
  • AmazonDynamoDBFullAccess (or create a least-privilege policy targeting ItemsTable)
  1. Name the role LambdaDynamoDBAccessRole and click Create role.

Step 3: Implement the AWS Lambda Function

  1. Open the AWS Lambda console and click Create function.
  2. Select Author from scratch:
  • Function name: itemsHandler
  • Runtime: Python 3.12
  • Execution role: Use an existing role (LambdaDynamoDBAccessRole)
  1. Replace the default function code with the following snippet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import json
import boto3

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('ItemsTable')

def lambda_handler(event, context):
http_method = event.get('requestContext', {}).get('http', {}).get('method', '')

if http_method == 'POST':
body = json.loads(event.get('body', '{}'))
item_id = body.get('itemId')
name = body.get('name')

if not item_id or not name:
return {
'statusCode': 400,
'body': json.dumps({'error': 'itemId and name are required'})
}

table.put_item(Item={'itemId': item_id, 'name': name})
return {
'statusCode': 201,
'body': json.dumps({'message': 'Item created successfully', 'itemId': item_id})
}

elif http_method == 'GET':
item_id = event.get('queryStringParameters', {}).get('itemId')
if not item_id:
return {
'statusCode': 400,
'body': json.dumps({'error': 'Query parameter itemId is required'})
}

response = table.get_item(Key={'itemId': item_id})
item = response.get('Item')

if not item:
return {
'statusCode': 404,
'body': json.dumps({'error': 'Item not found'})
}

return {
'statusCode': 200,
'body': json.dumps(item)
}

return {
'statusCode': 405,
'body': json.dumps({'error': 'Method not allowed'})
}
  1. Choose Deploy to save and publish your code.

Step 4: Configure API Gateway

  1. Open the Amazon API Gateway console and select Build under HTTP API.
  2. Configure your integration:
  • Select Add integration and choose Lambda.
  • Pick your AWS Region and choose itemsHandler.
  • Set API name to ItemsServiceApi.
  1. Configure routes:
  • POST /items
  • GET /items
  1. Proceed through the wizard and click Create.
  2. Copy the generated Invoke URL from the stage dashboard.

Step 5: Test the Endpoints

Using curl or an API testing tool, send a test payload:

Write an Item (POST):

1
2
3
curl -X POST https://<your-api-id>.execute-api.<region>.amazonaws.com/items \
-H "Content-Type: application/json" \
-d '{"itemId": "101", "name": "Cloud Architecture Guide"}'

Retrieve the Item (GET):

1
curl -X GET "https://<your-api-id>.execute-api.<region>.amazonaws.com/items?itemId=101"

Key Takeaways

  • Zero Idle Costs: You only pay per request and execution duration.
  • Elastic Scalability: Automatic scaling handles unpredictable spikes without capacity planning.
  • Separation of Concerns: Decoupled components make it straightforward to add authentication (such as Amazon Cognito) or asynchronous queues (like Amazon SQS).
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article