π A fully serverless CRUD API built with AWS Lambda, API Gateway, and DynamoDB.
Designed for beginners learning Python + AWS Cloud Integration.
A fully serverless To-Do API built with AWS Lambda, API Gateway, and DynamoDB β designed for beginners learning AWS Cloud & Python integration.
This app supports Create, Read, Update, and Delete (CRUD) operations using a single Lambda function.
- Single Lambda function handles all CRUD operations
- DynamoDB for To-Do storage
- API Gateway provides REST endpoints
- 100 % Serverless β no servers to manage
- Written in Python using
boto3
ββββββββββββββββββββββββββββββ
β Client (Postman / UI) β
ββββββββββββββββ¬βββββββββββββββ
β HTTPS
βΌ
ββββββββββββββββββββββββββββββ
β Amazon API Gateway β
β Routes: /todos , /todos/{id} β
ββββββββββββββββ¬βββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββ
β AWS Lambda (Python) β
β Single Function: CRUD Ops β
ββββββββββββββββ¬βββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββ
β Amazon DynamoDB Table β
β Table: TodoTable (id: str) β
ββββββββββββββββββββββββββββββ
- Go to AWS Console β DynamoDB β Tables β Create table
- Table name β
TodoTable - Partition key β
id(String) - Leave defaults β Create Table
- Go to AWS Console β Lambda β Create function
- Choose Author from scratch
- Function name β
ServerlessToDoFunction - Runtime β Python 3.9 or later
- Permissions β Attach AmazonDynamoDBFullAccess
- Click Create Function
- Paste your
lambda_function.pycode in the editor - Click Deploy
π§© This one function handles all 4 methods (POST, GET, PUT, DELETE)
- API Gateway β Create API β HTTP API β Build
- Name β
ToDoAPI - Create these routes:
| Method | Path | Description |
|---|---|---|
| POST | /todos |
Create To-Do |
| GET | /todos |
Get all To-Dos |
| PUT | /todos/{id} |
Update To-Do |
| DELETE | /todos/{id} |
Delete To-Do |
- For each route, choose:
- Integration type β Lambda
- Function β
ServerlessToDoFunction
- Deploy the API β Create a stage called
prod - Copy your Invoke URL β example:
https://abc123.execute-api.ap-south-1.amazonaws.com/prod
| Operation | Method | Endpoint | Body Example |
|---|---|---|---|
| Create | POST | /todos |
{ "task": "Learn AWS Lambda" } |
| Read | GET | /todos |
β |
| Update | PUT | /todos/{id} |
{ "status": "completed" } |
| Delete | DELETE | /todos/{id} |
β |
Example URL:
https://abc123.execute-api.ap-south-1.amazonaws.com/prod/todos
If you prefer to test or modify the API locally before deploying to AWS:
python -m venv venv
venv\Scripts\activate # On Windows
source venv/bin/activate # On Mac/Linuxpip install -r requirements.txtaws configurepython lambda_function.pycurl -X POST http://localhost:8000/todos -H "Content-Type: application/json" -d '{"task": "Test local To-Do", "status": "pending"}'Input
{
"task": "Complete AWS Serverless To-Do App",
"status": "pending"
}Output
{
"message": "ToDo created",
"item": {
"id": "e43664c5-6ebc-4d28-987a-cc2c99b5fdee",
"task": "Complete AWS Serverless To-Do App",
"status": "pending",
"created_at": "2025-11-03T10:51:40.727920"
}
}Output
[
{
"id": "e43664c5-6ebc-4d28-987a-cc2c99b5fdee",
"task": "Complete AWS Serverless To-Do App",
"status": "pending",
"created_at": "2025-11-03T10:51:40.727920"
}
]Input
{
"status": "completed"
}Output
{
"message": "ToDo updated",
"item": {
"id": "e43664c5-6ebc-4d28-987a-cc2c99b5fdee",
"task": "Complete AWS Serverless To-Do App",
"status": "completed",
"created_at": "2025-11-03T10:51:40.727920"
}
}Output
{
"message": "ToDo deleted successfully",
"deleted_id": "e43664c5-6ebc-4d28-987a-cc2c99b5fdee"
}This projectβs Lambda function can be tested in two ways β connected to AWS or offline.
If you have AWS CLI configured (aws configure), and a DynamoDB table named TodoTable, follow these steps:
python -m venv venv
venv\Scripts\activate
pip install -r requirements.txt
python lambda_function.pyYouβll see the simulated event result printed in your terminal.
Example output:
{
"statusCode": 201,
"body": "{\"message\": \"ToDo created\", \"item\": {\"id\": \"abc123\", \"task\": \"Learn AWS Serverless\", \"status\": \"pending\"}}"
}To test without AWS:
- Open
lambda_function.py - Add this code block before your DynamoDB initialization:
class MockTable: def __init__(self): self.storage = {} def put_item(self, Item): self.storage[Item["id"]] = Item def scan(self): return {"Items": list(self.storage.values())} def update_item(self, Key, UpdateExpression=None, ExpressionAttributeNames=None, ExpressionAttributeValues=None, ReturnValues=None): item = self.storage.get(Key["id"]) if not item: return {"Attributes": {}} if ":s" in ExpressionAttributeValues: item["status"] = ExpressionAttributeValues[":s"] if ":t" in ExpressionAttributeValues: item["task"] = ExpressionAttributeValues[":t"] self.storage[Key["id"]] = item return {"Attributes": item} def delete_item(self, Key): self.storage.pop(Key["id"], None) # Uncomment below line for offline testing # table = MockTable()
- Comment out your DynamoDB line:
# table = dynamodb.Table('TodoTable') - Run:
python lambda_function.py
Example output:
{
"statusCode": 201,
"body": "{\"message\": \"ToDo created (mock)\", \"item\": {\"id\": \"1234\", \"task\": \"Test offline mode\", \"status\": \"pending\"}}"
}Avinash S
AWS Cloud Engineer | Python Developer
π GitHub Profile