A fully serverless REST API for managing tasks, built entirely on AWS. This project demonstrates how to wire together API Gateway, AWS Lambda, and DynamoDB into a working CRUD backend, with IAM handling permissions and CloudWatch handling observability.
API Gateway receives HTTP requests and routes them to a single Lambda function based on the HTTP method. The Lambda function uses the AWS SDK v3 to perform CRUD operations against a DynamoDB table, and every invocation is logged to CloudWatch for monitoring and debugging.
| Service | Purpose |
|---|---|
| Amazon API Gateway | Exposes REST endpoints (GET, POST, PATCH, DELETE) |
| AWS Lambda | Runs the business logic (Node.js, AWS SDK v3) |
| Amazon DynamoDB | NoSQL table storing task records |
| AWS IAM | Grants Lambda least-privilege access to DynamoDB |
| Amazon CloudWatch | Logs and monitors API/Lambda execution |
| Postman | Used to test and validate the deployed API |
Create a table named tasks with id as the partition key (String).
Create a new Lambda function (Node.js runtime) that will handle all CRUD requests coming from API Gateway.
The Lambda function needs permission to read/write to the DynamoDB table. Attach an IAM policy to the Lambda's execution role granting the necessary DynamoDB actions (e.g. Scan, PutItem, UpdateItem, DeleteItem), along with the basic Lambda execution policy for CloudWatch Logs.
Paste the code from crudcode.mjs into the Lambda function and deploy it. It routes incoming requests to the appropriate handler based on event.httpMethod.
Create a new REST API in API Gateway that will sit in front of the Lambda function.
Add a resource (e.g. /tasks) under the REST API.
Add each HTTP method to the resource and integrate them with the Lambda function.
GET method
POST method
PATCH method
DELETE method
Deploy the API to a stage (e.g. prod) to get a public invoke URL.
Hitting the deployed GET URL directly in the browser returns the current list of tasks from DynamoDB.
Create a workspace in Postman to organize and test all four endpoints (GET, POST, PATCH, DELETE).
After sending a POST request, check the DynamoDB console to confirm the new task item was created.
Send a PATCH request with updated task data.
Confirm the table reflects the updated task data.
Send a DELETE request and confirm the task is removed from the table.
| Method | Description | Body |
|---|---|---|
GET |
Returns all tasks | — |
POST |
Creates a new task | { "name": "string", "completed": boolean } |
PATCH |
Updates an existing task | { "id": "string", "name": "string", "completed": boolean } |
DELETE |
Deletes a task | { "id": "string" } |
CloudWatch Logs is enabled on the Lambda function, so every invocation — including errors — can be traced in the CloudWatch console for debugging and monitoring API health.

.
├── README.md
├── lambda/
│ └── index.mjs # Lambda handler code
└── screenshots/ # Setup and testing screenshots
- Create a DynamoDB table named
taskswithidas the partition key. - Create a Lambda function and paste in the handler code above.
- Attach an IAM policy to the Lambda execution role granting DynamoDB and CloudWatch Logs permissions.
- Create a REST API in API Gateway with a
/tasksresource. - Add GET, POST, PATCH, and DELETE methods, each integrated with the Lambda function.
- Deploy the API to a stage to get your invoke URL.
- Test each endpoint using Postman (or curl/browser for GET).