12

I started my Visual Studio project from AWS SDK template. It uses IDynamoDBContext in the function and IAmazonDynamoDB in the tests. Everything worked to save and received documents when I received them with an id (hash). But it stopped to work when I added a range to my table. All my test were against AWS dynamoDb. But I got it to work in 2 ways. The first way were when I downloaded the local instance of dynamoDb. The second were when I replaced IDynamoDBContext to IAmazonDynamoDB in my function (so it used the same interface in both the function and in my test class). I don't know what the correct solution is, but why use 2 interfaces in the first place? Should I keep digging in why it didn't work with different interfaces or should I only use one of them?

        // IDynamoDBContext (default) - Didn't save my item (did save it in local DynamoDB)
        var test = new Test
        {
            UserId = "Test",
            Id = 1
        };

        await DDBContext.SaveAsync<Test>(test);

        // IAmazonDynamoDB - Did save my item
        var putItemRequest = new PutItemRequest
        {
            TableName = "TestTable",
            Item = new Dictionary<string, AttributeValue>()
            {
                { "UserId", new AttributeValue { S = "Test" }},
                { "Id", new AttributeValue { N = "1" }}
            }
        };
        await DDBContext.PutItemAsync(putItemRequest);

My test:

            var item = new GetItemRequest
        {
            TableName = "TestTable",
            Key = new Dictionary<string, AttributeValue>
            {
                { "UserId", new AttributeValue { S = "Test" } },
                { "Id", new AttributeValue { N = "1" } },
            },
        };
        Assert.True((await this.DDBClient.GetItemAsync(item)).Item.Count > 0);
thatsIT
  • 2,085
  • 6
  • 29
  • 43
  • Did you update your Test class (C# Object which matches the table) with the Sort Key Attribute [DynamoDBRangeKey] ? Like this example: https://docs.aws.amazon.com/sdk-for-net/v2/developer-guide/dynamodb-intro.html#dynamodb-intro-apis-object-persistence – Abhaya Chauhan Jan 01 '18 at 22:07
  • @AbhayaChauhan Yes I have that attribute. – thatsIT Jan 02 '18 at 06:58

1 Answers1

14

We probably need someone on the AWS .Net SDK team to speak to this but here is my best insight.

Amazon documentation is always fun.

The documentation does not make it overly clear but IDynamoDBContext is found in the Amazon.DynamoDbv2.DataModel namespace which is used for object persistence data access.

So I think the IAmazonDynamoDB interface is used for general API calls against the DynamoDB service. The two modes have overlapping functionality in that both can work with given items in a dynamoDb table.

The docs, of course, are really clear in that for IDynamoDbContext it says

Context interface for using the DataModel mode of DynamoDB. Used to interact with the service, save/load objects, etc.

https://docs.aws.amazon.com/sdkfornet/v3/apidocs/Index.html

For IAmazonDynamoDB it says

Interface for accessing DynamoDB Amazon DynamoDB

IAmazonDynamoDB is from the Amazon.DynamoDbv2 namespace and IDynamoDBContext is found in the Amazon.DynamoDbv2.DataModel.

If you look at the documentation for them both though you will see by looking at the methods the actions each can performance are very different.

IAmazonDynamoDb allows you to interact and work more with DynamoDb via:

  • Creating tables
  • Deleting tables
  • Creating global indexes and backups
  • etc.

You can still work directly with items but the number of API calls available via this interface is larger and allows working with the overall DynamoDB service.

While IDynamoDBContext allows you work directly with items in a given DynamoDb table with methods like:

  • Save
  • Query
  • Scan
  • Load

Consistency is always key in programming so always use the same interface for areas that are meant to do the same level of work. So your code and tests should be using the same interface as they are focused on the same work scope. Hopefully based on that additional clarification you know what interface you are after. If all your code is trying to do is work with items in a DynamoDb table then IDynamoDBContext is probably what you are after.

ToddB
  • 1,464
  • 1
  • 12
  • 27
  • I'll use IDynamoDBContext as you said in both my function and in my test class. I'll still keep my IAmazonDynamoDB to build my tables and then create my IDynamoDBContext like this: new DynamoDBContext(ddbClient, new DynamoDBContextConfig { Conversion = DynamoDBEntryConversion.V2 }); – thatsIT Jan 02 '18 at 13:07
  • But I don't get any item back when I use 'LoadAsync' against AWS (only if I use my local DynamoDB). Could it be something with my region when I test against AWS? var ddbClient = new AmazonDynamoDBClient(RegionEndpoint.EUWest1); – thatsIT Jan 02 '18 at 13:16
  • Hard to say given the current information as it is kind of a change in question. I don't know what your AWS setup is. I would assume you have verified your DynamoDb table has the same data in the EUWest1 region? Do you get an error or any information back? Can you use the same query in the web UI and get data? Probably easiest to open another question with those details. – ToddB Jan 02 '18 at 15:51
  • Your right. I opened another question, https://stackoverflow.com/questions/48076637/idynamodbcontext-saveasync-doesnt-save-my-item – thatsIT Jan 03 '18 at 12:03