7

I have two tables: Posts and Users

In the createPost mutation resolver, I set some default values do certain properties (think userId, createdAt timestamp, isDeleted flag etc). In addition, I would like to increment the User's numPosts counter.

Is this possible via the standard resolvers?

If not, what's the better alternative and why?

Alternative 1) Use DynamoDB Stream and trigger lambda function when new Post record is added that increments User's numPosts counter.

Alternative 2) Use a lambda resolver and move all logic there instead of the standard resolver.

Z Jones
  • 2,015
  • 4
  • 23
  • 42

3 Answers3

4

You can use a BatchPut Operation to update multiple tables at the same time. Refer to Amazon DynamoDB Batch Operations guide for more information.

You need to have a resolver like

{
  "version" : "2018-05-29",
  "operation" : "BatchGetItem",
  "tables" : {
    "Posts": {
        ...data
    },
    "NumPosts":{
        ...data
    }
  }
}
Karthik
  • 934
  • 9
  • 21
  • 1
    Yes, but there is a risk that one of the operations completes without the rest. – Z Jones May 29 '18 at 22:42
  • That is correct. You should then look at the response and handle it accordingly. `BatchPut` operation in AppSync gives you a flexibility to perform partial updates when writing to multiple tables. However note that, each update to an item is an atomic operation. I would suggest you use Alternative 1 - Use DynamoDB Stream and trigger lambda function when new Post record is added that increments User's numPosts counter. This way your state is eventually consistent. – Shankar Raju May 30 '18 at 04:40
1

I went the route of "Use a lambda resolver and move all logic there instead of the standard resolver." for my app.

You have a lot of control this way, solid logging, metric, and can pretty much do whatever you want, but you have to then pay for lambda.

Your option of watching a stream might make more sense if the other changes could happen after the fact, and having the data in an in-between state didn't matter.

Hard to assess what the best option is without total context.

Michael Economy
  • 608
  • 6
  • 21
-1

There are Update Expressions that can be used for DynamoDB; and it is apparently among the AppSync's Resolver Mapping Template Reference for DynamoDB. Going through the sample code given in the code, it should be useful for you to operate through some UpdateItem code as follows:

{
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key": {
        "id" : { "S" : "${context.arguments.id}" }
    },
    "update" : {
        "expression" :  "ADD numPosts :incrCount",
        "expressionValues" : {
           ":incrCount" : { "N" : 1 }
        }
    }
}

EDIT: This post assumes that your numPosts counter is kept as a field in your Users table.

vahdet
  • 6,357
  • 9
  • 51
  • 106