Daniel Donbavand

Documenting my Development Journey

Add and Get Items from an AWS DynamoDB Table in .NET Core

In this blog post we are going to two DynamoDB functions, the Put and Get functions. First we will look at how to Add 'Put' an item onto a DynamoDB table, then cover how we 'Get' either a single item or all items from a DynamoDB table.

If you haven't already read my previous blog post on Creating an AWS DynamoDB Table in .NET Core that is a good place to start. We covered creating a DynamoDB client and assigned Access and Secret keys to the client. We then used the client to create a DynamoDB table.

Let's start this post by looking at DynamoDBs PutItem.

PutItem – Create an Item.

Using the project that we created in Creating an AWS DynamoDB Table in .NET Core we are going to add another endpoint to our .NET Core WebAPI.

[Route("putitems")]
public IActionResult PutItem([FromQuery] int id, string replyDateTime)
{
    _putItem.AddNewEntry(id, replyDateTime);

    return Ok();
}

We will create a class PutItem and an interface IPutItem that we will be using to write the actual logic that will perform the Put.

IPutItem
PutItem

Bind this inside the ConfirgureServices method in the startup.cs class. This will allow us to dependency inject the class in classes that need to access items in the PutItem class.

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IPutItem, PutItem>();
}

Now we can initialize the class inside our controller, this will allow us to call off to the class and use the methods inside it.

private readonly IPutItem _putItem;

public DynamoDbController(IPutItem putItem,)
{
    _putItem = putItem;
}

Let's start implementing the code inside the PutItem class. This will allow us to interact with DynamoDB by adding items to our table.

PutItem.cs

Initialize the DynamoDB client at the top. Remember we created our client in Creating an AWS DynamoDB Table in .NET Core so if you are unsure how this is done, head along to that post where I explain how to set one up.

private readonly IAmazonDynamoDB _dynamoClient;

public PutItem(IAmazonDynamoDB dynamoClient)
{
    _dynamoClient = dynamoClient;
}

We are going to create three methods inside the PutItem class. The first will be a public method, that will simply call off to the other two methods. It will contain a call to a RequestBuilder builder, the request builder will build the request ready to be passed into our third method, PutItemAsync, this method will send the request to DynamoDB and return us back our results. This will all be past back to our first method that will then be returned back to the user.

Let's create the first method, 'AddNewEntry'

public async Task AddNewEntry(int id, string replyDateTime)
{
    var queryRequest = RequestBuilder(id, replyDateTime);

    await PutItemAsync(queryRequest);
}

In the request builder we are creating a PutItemRequest, the PutItemRequest is part of the Amazon.DynamoDBv2.Model.

private PutItemRequest RequestBuilder(int id, string replyDateTime)
{
    var item = new Dictionary<string, AttributeValue>
    {
	    {"Id", new AttributeValue {N = id.ToString()}},
	    {"ReplyDateTime", new AttributeValue {N = replyDateTime}}
    };

    return new PutItemRequest
    {
	    TableName = "TempDynamoDbTable",
	    Item = item
    };
}

Once we have built up our request and returned it, we then pass that request to the PutItem method.

private async Task PutItemAsync(PutItemRequest request)
{
    await _dynamoClient.PutItemAsync(request);
}

That's it, the following will add an item that contains “Id” and “ReplyDateTime” to our Dynamo table named TempDynamoDbTable.

Next let's have a look at how we can read items from our table.

GetItem – read an item

Let’s look at how we can get an item from our dynamoDB table.

There are a couple of ways we can get items back from our table. We can either get all of the items back from our table, or we can get items based on a filter.

Controller

Let’s first create another endpoint that will allow us to Get the items from our DynamoDB table.

We are going to create the endpoint to allow us to either enter an Id as a query parameter into the endpoint, that will return us back the specified entry that relates to the Id we are searching for. We will also make it so that the id is optional, so if no Id is entered, then all items will be returned.

[Route("getitems")]
public async Task<IActionResult> GetItem([FromQuery] int? id)
{
    var response = await _getItem.GetItems(id);

    return Ok(response);
}

You will noticed that I’ve made the int nullable by adding a ? to the int. This will allow us to hit the GetItem endpoint whether we specify an Id or not.

We now want to add a GetItem class along with a IGetItem

IGetItem
GetItem

Bind this to the startup.cs class in the ConfirgureServices

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IGetItem, GetItem>();
}
And initialize the class inside our controller

private readonly IGetItem _getItem;

public DynamoDbController(IGetItem gettem,)
{
    _getItem= getItem;
}

Now we can start implementing the code inside our GetItem class that will allows us to get the items from our DynamoDB table.

GetItem.cs

Initialize the DynamoDB client at the top

private readonly IAmazonDynamoDB _dynamoClient;

public GetItem(IAmazonDynamoDB dynamoClient)
{
    _dynamoClient = dynamoClient;
}

Now we can start adding the code needed to Get our items from the DynamoDB Table.

First we will create a method that will build the Scan request, then pass the request into the ScanAsync method ready to get our items.

public async Task<DyanmoTableItems> GetItems(int? id)
{
    var queryRequest = RequestBuilder(id);

    var result = await ScanAsync(queryRequest);

    return new DyanmoTableItems
    {
        Items = result.Items.Select(Map).ToList()
    };
}

The scan request includes things like the table we want to query and also what parameters we want to pass in as part of the request.

You will notice that I’m checking if we have a value in the Id, if we don’t we return all items, if we do have a value in the Id, then we scan the table for that record inside our DynamoDB table.

private ScanRequest RequestBuilder(int? id)
{
    if (id.HasValue == false)
    {
        return new ScanRequest
        {
            TableName = "TempDynamoDbTable",
        };
    }

    return new ScanRequest
    {
        TableName = "TempDynamoDbTable",
        ExpressionAttributeValues = new Dictionary<string, AttributeValue> {
            {
                ":v_Id", new AttributeValue { N = id.ToString() }}
        },
        FilterExpression = "Id = :v_Id",
        ProjectionExpression = "Id, ReplyDateTime"
    };
}

Once we have built up our request, we can pass it into the ScanAysnc method. This will call off to our DynamoDB table in AWS.

private async Task<ScanResponse> ScanAsync(ScanRequest request)
{
    var response = await _dynamoClient.ScanAsync(request);

    return response;
}

You might have noticed in the method above, GetItems, we do some mapping of the results that we get back from DynamoDB. We store these in a model we need to create.

return new DyanmoTableItems
{
    Items = result.Items.Select(Map).ToList()
};

Above is the code inside our GetItem method and below is the mapper that will map the results we get back from DynamoDB and map them to our model.

private Item Map(Dictionary<string, AttributeValue> result)
{
    return new Item
    {
        Id = Convert.ToInt32(result["Id"].N),
        ReplyDatetime = result["ReplyDateTime"].N
    };
}

Let’s have a look at what the model looks like

public class DyanmoTableItems
{
    public IEnumerable<Item> Items { get; set; }
}

public class Item
{
    public int Id { get; set; }
    public string ReplyDatetime { get; set; }
}

Summary

In this blog we have covered how we can add items to our DynamoDB table, We then looked at how we can retrieve the items with either a filter or if no filter request is passed in we then return all items.

I have create Youtube tutorials that take you through everything discussed above.