jsonamazon-web-servicesaws-api-gatewayvtl

Apache VTL - Copy node


Is there a way to do deep copy using apache VTL? I was trying to use x-amazon-apigateway-integration using requestTemplates. The input JSON is as shown below,

{
  "userid": "21d6523137f6",
  "time": "2020-06-16T15:22:33Z",
  "item": {
    "UserID" : { "S": "21d6523137f6" },
    <... some complex json nodes here ...>,
    "TimeUTC" : { "S": "2020-06-16T15:22:33Z" },
  }
} 

The requestTemplate is as shown below,

        requestTemplates:
          application/json: !Sub
            - |
              #set($inputRoot = $input.path('$'))
              {
                "TableName": "${tableName}",
                "ConditionExpression": "attribute_not_exists(TimeUTC) OR TimeUTC > :sk",
                "ExpressionAttributeValues": {
                  ":sk":{
                    "S": "$util.escapeJavaScript($input.path('$.time'))"
                  }
                },
                "Item": "$input.path('$.item')", <== Copy the entire item over to Item.
                "ReturnValues": "ALL_OLD",
                "ReturnConsumedCapacity": "INDEXES",
                "ReturnItemCollectionMetrics": "SIZE"
              }
            - {
            tableName: !Ref EventsTable
            }

The problem is, the item gets copied like,

  "Item": "{UserID={S=21d6523137f6}, Lat={S=37.33180957}, Lng={S=-122.03053391}, ... other json elements..., TimeUTC={S=2020-06-16T15:22:33Z}}",

As you can see, the whole nested json become a single atribute. While I expected it to become a fully blown json node on its own like below,

  "Item": {
    "UserID" : { "S": "21d6523137f6" },
    "Lat": { "S": "37.33180957" },
    "Lng": { "S": "-122.03053391" },
    <.... JSON nodes ...>
    "TimeUTC" : { "S": "2020-06-20T15:22:33Z" }
  },

Is it possible to deep/nested copy operation on a json node like above without doing the kung-fu of iterating the node and appending the childs o a json node variable etc...

btw, I'm using AWS API Gateway request template, so it may not support all the Apache VTL templating options.


Solution

  • You need to use the $input.json method instead of $input.path.

    "Item": $input.json('$.item'),
    

    Note that I removed the double quotes.

    If you had the double quotes because you want to stringify $.item, you can do that like so:

    "Item": "$util.escapeJavaScript($input.json('$.item'))",