0

In Amazon API gateway I'm using a body mapping template to transform the request. I found that keeping track of the commas was cumbersome (especially with multiple optional parameters) so I came up with the following:

{
    "context": { /* context params */ },
    "request": {
        #foreach($queryParam in $input.params().querystring.keySet())
            "$queryParam" : "$input.params().querystring.get($queryParam)"
            #if($foreach.hasNext),#end
        #end
    }
} 

The issue I find with this is that when $input.params().querystring.get($queryParam) is an integer (and shouldn't be enclosed with quotes) then it doesn't work. That seems fair enough, but how do I improve this to check if $input.params().querystring.get($queryParam) is a string, so that I can subsequently wrap it in quotation marks?

Request

http://www.somewebsite.com/apiendpoint?id=4&name=Terry&aliases=[Tel,Terry]

Transformation

{
    "id": "4",
    "name": "Terry",
    "aliases": "[Tel,Terry]"
}

Expected Transformation

{
    "id": 4,
    "name": "Terry",
    "aliases": ["Tel","Terry"]
}
ediblecode
  • 11,701
  • 19
  • 68
  • 116
  • 1
    What does VTL do if you try to add 0 to a string? if value + 0 == value *might* serve as a "looks like an integer" test. Or you could put a dummy parameter at the end, which makes keeping track of commas less of an issue, since the last real parameter has a comma after it, followed by `"dummy": true }` making valid JSON. Random ideas for your consideration. Or nest some if tests to compare the current parameter against the list of known numeric parameters and quote accordingly. – Michael - sqlbot Apr 20 '18 at 00:32
  • It's not clear if you have the problem on `$queryParam` or on `$input.params().querystring.get($queryParam)`. Can you show us the **expected** generated content against the **actual** generated content? – Claude Brisson Apr 20 '18 at 08:56
  • @ClaudeBrisson Thanks for the pointers, see edit – ediblecode Apr 20 '18 at 09:30

1 Answers1

0

Then you would do something like:

{
    "context": { /* context params */ },
    "request": {
        #foreach($queryParam in $input.params().querystring.keySet())
            #set($value = $input.params().querystring.get($queryParam))
            #set($isNum = $value.matches('[-+]?\d+(\.\d+)?'))
            "$queryParam" : #if(!$isNum)"#end$value#if(!$isNum)"#end
            #if($foreach.hasNext),#end
        #end
    }
}
Claude Brisson
  • 4,085
  • 1
  • 22
  • 30
  • Won't this fail if the parameter is meant to be a string, but only has digits in it? E.g. UK number plate will generally have letters, but could also be personalised and contain only digits – ediblecode Apr 30 '18 at 13:20
  • @ediblecode It's for you to choose the correct criteria. Instead of the proposal, you can also decide to display a string or a number depending on the field name. Like: `#set($fieldIsNumber = {'plate' : false, 'km': true})` and then, instead of a regex, you'll use `#set($isNum = $fieldIsNumber[$queryParam]) `. – Claude Brisson May 01 '18 at 10:53