- Newest
- Most votes
- Most comments
Hi snewton,
I got your back. You're on the right track here!
tl;dr- change
$!{expValues.put(":data", $util.dynamodb.toDynamoDBJson($context.arguments.input.data) )}
to
$!{expValues.put(":data", $util.dynamodb.toDynamoDB($context.arguments.input.data) )}
.
If you run your resolver code as-is using the Console resolver tester, you'll notice the output of your code is
...
"expressionValues": {
":updatedAt": { "S": "2019-07-10T20:35:30.000Z" },
":data": "{\"S\":\"[{\\\"xyz\\\": 101}]\"}"
}
...
You'll notice the difference here is that the ":updatedAt" key prints a DynamoDB type object (See: https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request), while the ":data" key prints a DynamoDB type object but as a string. This is why you got the error "Expecting JSON object..." because the DynamoDB resolver is expecting a JSOn object to specify the type of value to write to DynamoDB.
If you look at the DynamoDB Resolver Util reference (See: https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference.html#dynamodb-helpers-in-util-dynamodb), you'll see that the method $util.dynamodb.toDynamoDBJson(Object) returns a String, which you save into the expValues map, which then gets passed to $util.toJson(Object) which expects an input object, and will return it as a string which gets printed as output in the vtl. I understand the confusion because there are a few layers here: How you store the values in the expValues map, and the fact that all variables must evaluate to a string to be printed as the output of the VTL (which overall is a string intending to represent a JSON object understood by the DynamoDB data source.
Looking further at the resolver reference, you see $util.dynamodb.toDynamoDB(Object) which returns a Map, the same as the literal map you defined in ":updatedAt", { "S": "$now" }, which will give you the expected output to be printed under expressionValues. I hope this helps clear things up!
That may be a better solution.
I had gotten another method working:
$!{expValues.put(":data", $util.parseJson($util.dynamodb.toDynamoDBJson($context.arguments.input.data)) )}
which adds the parseJson layer to get the same result but is almost certainly less efficient.
The solution by @AaronHarris is more clear and also works. Sorry for not updating the thread with my previous answer but this is solved now.
Relevant content
- asked 3 years ago
- Accepted Answerasked a month ago
- AWS OFFICIALUpdated 2 years ago
- AWS OFFICIALUpdated 2 years ago
- AWS OFFICIALUpdated a year ago