Building a Serverless REST API with API Gateway, Lambda, and DynamoDB
Naveen Teja
3/2/2026

The serverless stack of API Gateway + Lambda + DynamoDB is one of the most searched architectural patterns on AWS. When implemented correctly, this combination eliminates server management entirely, scales to millions of requests automatically, and costs nearly zero at low traffic volumes due to pay-per-invocation pricing.
The architecture works as follows: API Gateway acts as the front door, handling authentication (via Cognito or Lambda authorizers), request validation, throttling, and CORS. It forwards validated requests to Lambda, which contains your business logic. Lambda reads and writes to DynamoDB using the AWS SDK and returns structured responses back through API Gateway to the client.
The most common mistakes when building this stack are: not enabling DynamoDB point-in-time recovery, neglecting to set Lambda reserved concurrency limits (which can drain your account concurrency budget), and building chatty APIs that call DynamoDB once per item instead of using BatchGetItem. The Terraform below provisions the complete stack — DynamoDB table with on-demand billing, a Lambda function with least-privilege IAM, and API Gateway with Lambda proxy integration.
resource "aws_dynamodb_table" "items" {
name = "api-items"
billing_mode = "PAY_PER_REQUEST"
hash_key = "PK"
range_key = "SK"
attribute {
name = "PK"
type = "S"
}
attribute {
name = "SK"
type = "S"
}
point_in_time_recovery {
enabled = true
}
}
resource "aws_lambda_function" "api_handler" {
filename = "function.zip"
function_name = "api-items-handler"
role = aws_iam_role.lambda_exec.arn
handler = "index.handler"
runtime = "nodejs20.x"
reserved_concurrent_executions = 100
environment {
variables = {
TABLE_NAME = aws_dynamodb_table.items.name
}
}
}
resource "aws_apigatewayv2_api" "http_api" {
name = "items-api"
protocol_type = "HTTP"
cors_configuration {
allow_origins = ["https://www.naveenteja.cloud"]
allow_methods = ["GET", "POST", "DELETE"]
allow_headers = ["Content-Type", "Authorization"]
}
}
resource "aws_apigatewayv2_integration" "lambda" {
api_id = aws_apigatewayv2_api.http_api.id
integration_type = "AWS_PROXY"
integration_uri = aws_lambda_function.api_handler.invoke_arn
}You might also like

Migrating from EC2 to AWS Fargate: A Step-by-Step Guide

Multi-Region Active-Active Architecture on AWS

Implementing AWS GuardDuty with Automated Threat Response

OpenTofu vs Terraform in 2024: Migration Guide and Key Differences

Zero-Trust Networking on AWS with IAM Identity Center and SCPs
