On this page
article
Lambda + API Gateway
Expose AWS Lambda functions as REST APIs with API Gateway — routing, request/response mapping, CORS, and authentication.
API Gateway turns Lambda functions into HTTP endpoints — the standard pattern for serverless REST APIs on AWS.
Architecture
Client → API Gateway → Lambda → DynamoDB / S3 / etc.
↓
CloudWatch Logs
Lambda Handler for HTTP
API Gateway sends events in a specific format:
import json
def lambda_handler(event, context):
http_method = event["httpMethod"]
path = event["path"]
query = event.get("queryStringParameters") or {}
body = json.loads(event.get("body") or "{}")
if http_method == "GET" and path == "/items":
items = get_all_items()
return response(200, items)
if http_method == "GET" and path.startswith("/items/"):
item_id = path.split("/")[-1]
item = get_item(item_id)
if not item:
return response(404, {"error": "Not found"})
return response(200, item)
if http_method == "POST" and path == "/items":
item = create_item(body)
return response(201, item)
if http_method == "DELETE" and path.startswith("/items/"):
item_id = path.split("/")[-1]
delete_item(item_id)
return response(204, None)
return response(404, {"error": "Route not found"})
def response(status_code, body):
return {
"statusCode": status_code,
"headers": {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
"body": json.dumps(body) if body is not None else "",
}
Deploy with AWS SAM
AWS SAM simplifies API + Lambda deployment:
# template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
ItemsApi:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: app.lambda_handler
Runtime: python3.12
MemorySize: 256
Timeout: 30
Events:
GetItems:
Type: Api
Properties:
Path: /items
Method: GET
CreateItem:
Type: Api
Properties:
Path: /items
Method: POST
GetItem:
Type: Api
Properties:
Path: /items/{id}
Method: GET
DeleteItem:
Type: Api
Properties:
Path: /items/{id}
Method: DELETE
sam build
sam deploy --guided
# Outputs: API endpoint URL
CORS Configuration
For browser clients, handle OPTIONS preflight:
def lambda_handler(event, context):
if event["httpMethod"] == "OPTIONS":
return {
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,POST,DELETE,OPTIONS",
"Access-Control-Allow-Headers": "Content-Type,Authorization",
},
"body": "",
}
...
Or configure CORS in API Gateway / SAM template:
Events:
GetItems:
Type: Api
Properties:
Path: /items
Method: GET
RestApiId: !Ref ServerlessApi
# Add to API resource:
# Cors:
# AllowMethods: "'GET,POST,DELETE,OPTIONS'"
# AllowHeaders: "'Content-Type,Authorization'"
# AllowOrigin: "'*'"
Authentication with Cognito / JWT
def lambda_handler(event, context):
# API Gateway validates JWT and passes claims
claims = event.get("requestContext", {}).get("authorizer", {}).get("claims", {})
user_id = claims.get("sub")
if not user_id:
return response(401, {"error": "Unauthorized"})
...
Configure a Cognito User Pool authorizer in API Gateway for automatic JWT validation.
DynamoDB Integration
import boto3
from decimal import Decimal
import json
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table("Items")
class DecimalEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Decimal):
return float(obj)
return super().default(obj)
def get_all_items():
return table.scan()["Items"]
def create_item(data):
import uuid
item = {"id": str(uuid.uuid4()), **data}
table.put_item(Item=item)
return item
Testing Locally
sam local start-api
curl http://127.0.0.1:3000/items
curl -X POST http://127.0.0.1:3000/items -d '{"name": "Test"}'
API Gateway vs Function URL
| Feature | API Gateway | Lambda Function URL |
|---|---|---|
| Routing | Path/method based | Single endpoint |
| Auth | Cognito, IAM, API keys | IAM, none |
| Rate limiting | Built-in | None |
| Caching | Yes | No |
| Cost | Per request | Free (Lambda only) |
Use API Gateway for production REST APIs. Function URLs for simple webhooks.
Related Chapters
- AWS Lambda Getting Started
- Lambda Best Practices
- Project: Serverless Image Processor
- FastAPI Auth — similar REST patterns
API Gateway + Lambda is the most common serverless API pattern on AWS.