amazon-web-servicesaws-appsyncvtl

AWS AppSync vtl make set null if argument is empty list


I want to update a 'person' item in my table. I want to update the persons name and his set of skills. It's also possible that we just use the updatePerson mutation to update the name. And we will update the skills later.

At that point the argument 'skills' is an empty list. However DynamoDB does not allow for empty sets.

Currently I am trying to work around this by first checking if the skills argument is an empty list. But it is still telling me "An string set may not be empty for key :skills".

This is my current request mapping template, but atm the isNullOrDefault check does not work.

#if ($util.isNullOrEmpty($context.arguments.skills))
  #set ($skills = $utils.dynamodb.toNullJson())
#else
  #set ($skills = $utils.dynamodb.toStringSetJson($context.arguments.skills))
#end

{
  "version" : "2018-05-29",
  "operation" : "UpdateItem",
  "key": {
    "id" : $utils.dynamodb.toDynamoDBJson($context.arguments.id)
  },
  "update" : {
    "expression" : "set #name = :name, #skills= :skills,
    "expressionNames" : {
      "#name": "name",
      "#skills": "skills",
    },
    "expressionValues" : {
      ":name" : $utils.dynamodb.toDynamoDBJson($context.arguments.name),
      ":skills" : $skills,
    }
  }
}

Do you know how I can set the set of skills if the skills argument is not an empty array and not set it if the skills argument is an empty array?


Solution

  • Instead of setting null into a string-set attribute, I think you just remove the attribute from the item item.skills = undefined.

    You can use SET, and REMOVE actions to achieve that. The update is dynamically generated based on the input of skills. Sample code (I haven't tested it myself)

    #set ($update = {
      "expression" : "set #name = :name remove #skills",
      "expressionNames" : {
        "#name": "name",
        "#skills": "skills"
      },
      "expressionValues" : {
        ":name" : $utils.dynamodb.toDynamoDBJson($context.arguments.name)
      }
    })
    
    #if (!$util.isNullOrEmpty($context.arguments.skills))
      #set ($update = {
        "expression" : "set #name = :name set #skills = $skill",
        "expressionNames" : {
            "#name": "name",
            "#skills": "skills"
        },
        "expressionValues" : {
            ":name" : $utils.dynamodb.toDynamoDBJson($context.arguments.name),
            ":skills" :$utils.dynamodb.toStringSetJson($context.arguments.skills),
        }
      })
    #end
    
    {
      "version" : "2018-05-29",
      "operation" : "UpdateItem",
      "key": {
        "id" : $utils.dynamodb.toDynamoDBJson($context.arguments.id)
      },
      "update" : $update // or maybe $util.toJson($update) 
    }