AppSync BatchPutItem not saving items
Asked Answered
M

3

6

I'm trying to batch put a number of items to DynamoDB using AppSync. When I call the resolver it throws no errors but nothing is saved to the database.

Schema

type BoxScore @model {
  id: ID!
  userId: String!
  gameVariant: String!
  complete: Boolean!
  failFact: BoxScoreFact @connection
  totalCorrect: Int!
}

type BoxScoreFact @model {
  id: ID!
  left: Int!
  right: Int!
  gameVariant: String!
  timestamp: Int!
  correct: Boolean!
}

input BatchAddCreateBoxScoreFactInput {
  id: ID
  left: Int!
  right: Int!
  gameVariant: String!
  timestamp: Int!
  correct: Boolean!
  boxScoreFactBoxScoreId: ID!
}

IAM Role:

        "Effect": "Allow",
        "Action": [
            "dynamodb:DeleteItem",
            "dynamodb:GetItem",
            "dynamodb:PutItem",
            "dynamodb:Query",
            "dynamodb:Scan",
            "dynamodb:UpdateItem",
            "dynamodb:BatchGetItem",
            "dynamodb:BatchWriteItem"
        ],

Resolver:

#set($factsdata = [])
#foreach($item in ${ctx.args.facts})
    $util.qr($factsdata.add($util.dynamodb.toMapValues($item)))
#end

{
    "version" : "2018-05-29",
    "operation" : "BatchPutItem",
    "tables" : {
        "TABLENAME": $utils.toJson($factsdata)
    }
}

Call from AppSync playground:

enter image description here

Response mapping template:

  #if($ctx.error)
      ## Append a GraphQL error for that field in the GraphQL response
      $utils.error($ctx.error.message, $ctx.error.message)
  #end

  {
      "boxScoreFacts": $util.toJson({"res": "no error", "ctx": $ctx}),
  }

Output template from Function test run:

enter image description here

DynamoDB Table

enter image description here

Where TABLENAME is set equal to the DynamoDB table name that is displayed in the DDB console. So something like BoxScoreFact-woieieie99392-prod.

The table is always empty and the response is null. This is lifted almost straight out of the example from the docs. Also, I should note, that putting one item using the normal create graphql function does put an item to the intended table.

What am I missing here?

Midland answered 25/8, 2019 at 22:36 Comment(9)
Could you provide your response mapping template?Wend
@Wend added. If the response mapping template is invalid would it prevent the put from happening entirely, i.e. no save to the table?Midland
You can try and enable logging for AppSync and see if there is anything interesting in the logs. Also what are the IAM permissions for your role?Avis
@Phil, not really, but you may not be seeing the error returning from DynamoDB, Could you try to raise an error instead of appending the error?Wend
@Wend The screen shot that shows the $ctx output from the resolver template is truncated, apparently not copiable, has error: null, and outError: []. So it doesn't seem like anything is going wrong. Also, I should note, that putting one item using the normal create graphql function does put an item to the intended table.Midland
Very weird this problem. Could you change your mutation return to string batchAddBoxScoreFacts(facts: [BatchAddCreateBoxScoreFactInput]): String and the response mapping to $util.toJson($ctx)? This way we'll have a full stringify response and get tips to solve your problem. You'll receive something like this: "{arguments={facts=[{boxScoreFactBoxScoreId=123, gameVariant=0}]}, identity=null, source=null, result={data={Test=[{gameVariant=0, boxScoreFactBoxScoreId=123}]}, unprocessedItems={Test=[]}}, request={...}, error=null, prev=null, stash={}, outErrors=[]}"Scrutinize
can we see your dynamodb schema?Aftmost
@Aftmost did you mean the graphql schema? addedMidland
@PhilAndrews I meant the dynamodb schema itself (has & range key). The graphql schema is a good information as well. While you're at it, can you give us BatchAddCreateBoxScoreFactInput schema as well?Aftmost
B
0

The lambda function of Appsync is called over the Serverless Appsync plugin and within this role the BatchWriteItem is missing in older versions. Within your package.json file try changing the plugin version to the latest or the GitHub version in which this problem is fixed.

This should fix it:

"devDependencies": {
   ....
   "serverless-appsync-plugin": "^1.1.0"
   ....
}

or

"devDependencies": {
   ....
   "serverless-appsync-plugin": "https://github.com/sid88in/serverless-appsync-plugin.git#e33b5cfd"
   ....
}
Biauriculate answered 28/8, 2019 at 11:11 Comment(2)
It shouldn't be necessary to use an additional package to get this to workMidland
Ok, I had exactly the same problem as you did so I was assuming you would be using this package. This was my solution which took forever to find.Biauriculate
H
0

It doesn't look like the mandatory id is being passed among your variables. You can try setting it automatically in your resolver:

#set($factsdata = [])
#foreach($item in ${ctx.args.facts})
    $util.qr($item.put("id", $util.defaultIfNullOrBlank($item.id, $util.autoId())))
    $util.qr($factsdata.add($util.dynamodb.toMapValues($item)))
#end

{
    "version" : "2018-05-29",
    "operation" : "BatchPutItem",
    "tables" : {
        "TABLENAME": $utils.toJson($factsdata)
    }
}
Hoagland answered 19/2, 2020 at 16:57 Comment(0)
N
0

The solution for me was to include the batch permissions in the IAM role "dynamodb:BatchGetItem" and "dynamodb:BatchWriteItem". Seems that this operations aren't included by default.

Final json policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:DeleteItem",
                "dynamodb:GetItem",
                "dynamodb:PutItem",
                "dynamodb:Query",
                "dynamodb:Scan",
                "dynamodb:UpdateItem",
                "dynamodb:BatchGetItem",
                "dynamodb:BatchWriteItem"
            ],
            "Resource": [
                "arn:aws:dynamodb:<region>:<account_id>:table/<TableName>",
                "arn:aws:dynamodb:<region>:<account_id>:table/<TableName>/*"
            ]
        }
    ]
}
Nuke answered 19/3, 2021 at 2:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.