To-do List API: Connecting DynamoDB with AWS Lambda in a .NET Core Application
Here, we’ll learn how to connect AWS Lambda to DynamoDB using .NET Core to build a serverless application. AWS Lambda allows you to run code without provisioning or managing servers, and DynamoDB is a fully managed NoSQL database service provided by AWS. Together, they enable you to build scalable, real-time, serverless applications.
Embark on a journey of continuous learning and exploration with DotNet-FullStack-Dev. Uncover more by visiting our https://dotnet-fullstack-dev.blogspot.com reach out for further information.
Real-Time Example: A Simple To-Do List Application
We’ll create a To-Do List API where users can create, retrieve, update, and delete tasks. The tasks will be stored in DynamoDB, and Lambda functions will handle the logic.
Prerequisites
- An AWS account.
- AWS CLI installed and configured.
- .NET Core SDK installed.
- Basic knowledge of AWS Lambda and DynamoDB.
Step 1: Set Up the DynamoDB Table
First, we need to create a DynamoDB table to store the tasks. Each task will have:
- A TaskId (Primary Key).
- A TaskName.
- A TaskStatus (e.g., Pending, Completed).
Create DynamoDB Table
You can use the AWS Management Console or AWS CLI to create the table. Here’s the command for creating a table using the AWS CLI:
aws dynamodb create-table \
--table-name ToDoList \
--attribute-definitions AttributeName=TaskId,AttributeType=S \
--key-schema AttributeName=TaskId,KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5
This command creates a table called ToDoList
with TaskId
as the primary key (a string).
Step 2: Create Lambda Function in .NET Core
Set Up the .NET Core Lambda Project
Create a new AWS Lambda project in .NET Core using the AWS Toolkit for .NET or the Amazon.Lambda.Templates package.
Run the following command to create a Lambda function project:
dotnet new lambda.EmptyFunction -n ToDoListLambda
cd ToDoListLambda
This creates a basic Lambda project named ToDoListLambda
.
Install AWS SDK for DynamoDB
Next, install the AWS SDK for DynamoDB to interact with DynamoDB from the Lambda function.
dotnet add package AWSSDK.DynamoDBv2
Step 3: Implement the Lambda Function to Handle CRUD Operations
We’ll implement Lambda functions to handle CRUD (Create, Read, Update, Delete) operations on tasks stored in the DynamoDB table.
Configure AWS Credentials
Ensure that your Lambda function has the necessary permissions to access DynamoDB. You can set this up using an IAM role with the AmazonDynamoDBFullAccess
policy.
Code: Lambda Handler for CRUD Operations
Create a Task in DynamoDB.
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using Amazon.Lambda.APIGatewayEvents;
using Amazon.Lambda.Core;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
// Lambda entry point
public class Function
{
private static readonly AmazonDynamoDBClient _dynamoDbClient = new AmazonDynamoDBClient();
public async Task<APIGatewayProxyResponse> CreateTask(APIGatewayProxyRequest request, ILambdaContext context)
{
var requestBody = Newtonsoft.Json.JsonConvert.DeserializeObject<TaskItem>(request.Body);
var item = new Dictionary<string, AttributeValue>
{
{ "TaskId", new AttributeValue { S = Guid.NewGuid().ToString() } },
{ "TaskName", new AttributeValue { S = requestBody.TaskName } },
{ "TaskStatus", new AttributeValue { S = "Pending" } }
};
var putItemRequest = new PutItemRequest
{
TableName = "ToDoList",
Item = item
};
await _dynamoDbClient.PutItemAsync(putItemRequest);
return new APIGatewayProxyResponse
{
StatusCode = 200,
Body = "Task created successfully!"
};
}
}
// Task model
public class TaskItem
{
public string TaskName { get; set; }
}
In this example:
- The
CreateTask
method is triggered by an API Gateway event. - The task details are parsed from the API request body and then inserted into DynamoDB using
PutItemAsync
.
Retrieve a Task from DynamoDB.
public async Task<APIGatewayProxyResponse> GetTask(APIGatewayProxyRequest request, ILambdaContext context)
{
var taskId = request.PathParameters["id"];
var getItemRequest = new GetItemRequest
{
TableName = "ToDoList",
Key = new Dictionary<string, AttributeValue>
{
{ "TaskId", new AttributeValue { S = taskId } }
}
};
var response = await _dynamoDbClient.GetItemAsync(getItemRequest);
if (response.Item == null || response.Item.Count == 0)
{
return new APIGatewayProxyResponse
{
StatusCode = 404,
Body = "Task not found"
};
}
var task = new TaskItem
{
TaskName = response.Item["TaskName"].S
};
return new APIGatewayProxyResponse
{
StatusCode = 200,
Body = Newtonsoft.Json.JsonConvert.SerializeObject(task)
};
}
Here, we retrieve a task by its TaskId
using the GetItemAsync
method.
Update a Task in DynamoDB.
public async Task<APIGatewayProxyResponse> UpdateTask(APIGatewayProxyRequest request, ILambdaContext context)
{
var taskId = request.PathParameters["id"];
var requestBody = Newtonsoft.Json.JsonConvert.DeserializeObject<TaskItem>(request.Body);
var updateItemRequest = new UpdateItemRequest
{
TableName = "ToDoList",
Key = new Dictionary<string, AttributeValue>
{
{ "TaskId", new AttributeValue { S = taskId } }
},
ExpressionAttributeNames = new Dictionary<string, string>
{
{ "#T", "TaskName" },
{ "#S", "TaskStatus" }
},
ExpressionAttributeValues = new Dictionary<string, AttributeValue>
{
{ ":taskName", new AttributeValue { S = requestBody.TaskName } },
{ ":taskStatus", new AttributeValue { S = requestBody.TaskStatus } }
},
UpdateExpression = "SET #T = :taskName, #S = :taskStatus",
ReturnValues = "ALL_NEW"
};
var response = await _dynamoDbClient.UpdateItemAsync(updateItemRequest);
return new APIGatewayProxyResponse
{
StatusCode = 200,
Body = "Task updated successfully!"
};
}
This updates the task details (like name and status) using the UpdateItemAsync
method.
Delete a Task from DynamoDB.
public async Task<APIGatewayProxyResponse> DeleteTask(APIGatewayProxyRequest request, ILambdaContext context)
{
var taskId = request.PathParameters["id"];
var deleteItemRequest = new DeleteItemRequest
{
TableName = "ToDoList",
Key = new Dictionary<string, AttributeValue>
{
{ "TaskId", new AttributeValue { S = taskId } }
}
};
await _dynamoDbClient.DeleteItemAsync(deleteItemRequest);
return new APIGatewayProxyResponse
{
StatusCode = 200,
Body = "Task deleted successfully!"
};
}
This deletes the task from DynamoDB using DeleteItemAsync
.
Step 4: Deploy the Lambda Function
To deploy your Lambda function, you’ll use the AWS Lambda deployment tools or the AWS Management Console. Here’s how to deploy using the AWS CLI.
Package the .NET Lambda Function
dotnet lambda package -o ToDoListLambda.zip
Deploy the Lambda Function
aws lambda create-function --function-name ToDoListLambda \
--zip-file fileb://ToDoListLambda.zip \
--handler ToDoListLambda::ToDoListLambda.Function::FunctionHandler \
--runtime dotnet6 \
--role arn:aws:iam::123456789012:role/execution_role
Ensure that the Lambda function has permission to access DynamoDB.
Step 5: Test the Lambda Function with API Gateway
You can set up AWS API Gateway to trigger the Lambda functions. Each API Gateway endpoint can be configured to handle the different CRUD operations.
For example:
- POST
/tasks
→CreateTask
- GET
/tasks/{id}
→GetTask
- PUT
/tasks/{id}
→UpdateTask
- DELETE
/tasks/{id}
→DeleteTask
You can configure these routes in the API Gateway and link them to your Lambda function.
Conclusion
We’ve successfully connected an AWS Lambda function to DynamoDB using .NET Core. We implemented a simple To-Do List application that allows users to create, retrieve, update, and delete tasks. By leveraging AWS Lambda and DynamoDB, we built a serverless, scalable, and cost-efficient solution.
Key takeaways:
- AWS Lambda provides a serverless environment to execute code in response to API Gateway requests.
- DynamoDB is a fully managed NoSQL database that integrates easily with Lambda using the AWS SDK.
- .NET Core offers a robust framework to build and deploy AWS Lambda functions efficiently.