Skip to content

Instantly share code, notes, and snippets.

@ryanray
Created October 4, 2015 01:24
Show Gist options
  • Save ryanray/668022ad2432e38493df to your computer and use it in GitHub Desktop.
Save ryanray/668022ad2432e38493df to your computer and use it in GitHub Desktop.
API Gateway application/www-form-urlencoded to application/json based on https://forums.aws.amazon.com/thread.jspa?messageID=673012&tstart=0#673012
## convert HTML POST data or HTTP GET query string to JSON
## get the raw post data from the AWS built-in variable and give it a nicer name
#if ($context.httpMethod == "POST")
#set($rawAPIData = $input.path('$'))
#elseif ($context.httpMethod == "GET")
#set($rawAPIData = $input.params().querystring)
#set($rawAPIData = $rawAPIData.toString())
#set($rawAPIDataLength = $rawAPIData.length() - 1)
#set($rawAPIData = $rawAPIData.substring(1, $rawAPIDataLength))
#set($rawAPIData = $rawAPIData.replace(", ", "&"))
#else
#set($rawAPIData = "")
#end
## first we get the number of "&" in the string, this tells us if there is more than one key value pair
#set($countAmpersands = $rawAPIData.length() - $rawAPIData.replace("&", "").length())
## if there are no "&" at all then we have only one key value pair.
## we append an ampersand to the string so that we can tokenise it the same way as multiple kv pairs.
## the "empty" kv pair to the right of the ampersand will be ignored anyway.
#if ($countAmpersands == 0)
#set($rawPostData = $rawAPIData + "&")
#end
## now we tokenise using the ampersand(s)
#set($tokenisedAmpersand = $rawAPIData.split("&"))
## we set up a variable to hold the valid key value pairs
#set($tokenisedEquals = [])
## now we set up a loop to find the valid key value pairs, which must contain only one "="
#foreach( $kvPair in $tokenisedAmpersand )
#set($countEquals = $kvPair.length() - $kvPair.replace("=", "").length())
#if ($countEquals == 1)
#set($kvTokenised = $kvPair.split("="))
#if ($kvTokenised[0].length() > 0)
## we found a valid key value pair. add it to the list.
#set($devNull = $tokenisedEquals.add($kvPair))
#end
#end
#end
## next we set up our loop inside the output structure "{" and "}"
{
#foreach( $kvPair in $tokenisedEquals )
## finally we output the JSON for this pair and append a comma if this isn't the last pair
#set($kvTokenised = $kvPair.split("="))
"$util.urlDecode($kvTokenised[0])" : #if($kvTokenised[1].length() > 0)"$util.urlDecode($kvTokenised[1])"#{else}""#end#if( $foreach.hasNext ),#end
#end
}
@crisvergara
Copy link

https://gist.github.com/ryanray/668022ad2432e38493df#file-aws-api-gateway-form-to-json-ftl-L49

Should change #if($kvTokenised[1].length() > 0) to #if($kvTokenised.size() > 1 && $kvTokenised[1].length() > 0)

That fixed keys with no corresponding value in the payload for me ie. foo=&bar=baz.

@199911
Copy link

199911 commented Mar 18, 2016

In line 5, should it be #set($rawAPIData = $input.path("$")) ?
Single quote seems not allowed.

@luisgjb
Copy link

luisgjb commented Jun 23, 2016

im having internal server error with postman 👎 , when i left an empty value for example :

name:

@winzig
Copy link

winzig commented Dec 13, 2016

Thank you @crisvergara, that was crucial for me as well.

@stephenbmfj
Copy link

This fails if a parameter key or value has a character that needs to be escaped in a JSON string (e.g.: %5C). Replace line 49 with:

"$util.escapeJavaScript($util.urlDecode($kvTokenised[0]))" : #if($kvTokenised[1].length() > 0)"$util.escapeJavaScript($util.urlDecode($kvTokenised[1]))"#{else}""#end#if( $foreach.hasNext ),#end

@stephenbmfj
Copy link

stephenbmfj commented Aug 28, 2018

This fails if a parameter value is empty. Replace line 49 with:

"$util.escapeJavaScript($util.urlDecode($kvTokenised[0]))":#if($kvTokenised.size() > 1)"$util.escapeJavaScript($util.urlDecode($kvTokenised[1]))"#{else}""#end#if( $foreach.hasNext ),#end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment