I want to parse 'statusCode' and 'body' values from API Gateway integration response using VTL and return those as a method response like this:
Request status: 201
Response body: {"firstName":"He","lastName":"Man","email":"he.man@eternia.com"}
My API Gateway Step Function integration is returning the following integration response body (this is before transformation, non-relevant attributes are removed from output):
{
"output": "{\"statusCode\":201,\"body\":{\"firstName\":\"He\",\"lastName\":\"Man\",\"email\":\"he.man@eternia.com\"}}"
}
I would assume this to work:
#set ($output = $util.parseJson($input.json('$.output')))
#set ($statusCode = $output.statusCode)
#set ($context.responseOverride.status = $statusCode)
$output.body
But status is not updated and body is empty
Request status: 200
Response body: <empty>
With this approach I can parse the body:
#set ($bodyObj = $util.parseJson($input.body))
#set ($output = $util.parseJson($bodyObj.output))
#set ($context.responseOverride.status = $output.statusCode)
$output.body
statusCode is updated but body is returned as object representation i.e. not JSON.
Request status: 201
Response body: {firstName=He, lastName=Man, email=he.man@eternia.com}
How to serialize $output.body correctly to JSON in above case? API Gateway doesn't seem to have $util.toJson function like AppSync does (https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-programming-guide.html)
I've confirmed parsing output-variable works correctly:
#set ($output = $util.parseJson($input.json('$.output')))
$output
Request status: 200
Response body: {"statusCode":201,"body":{"firstName":"He","lastName":"Man","email":"he.man@eternia.com"}}
Relevant reference documentation:
I ran into this exact issue. There indeed does not seem to be a way to convert to JSON directly, so I devised a way to write JSON to the API Gateway response using Apache VTL:
#set ($outputObj = $util.parseJson($input.path('$.output')))
#foreach ( $key in $outputObj.body.keySet() )
"$key": $outputObj.body[$key] #if ($foreach.hasNext),#end
#end
Hope this helps!
(This works for a simple use case like the one you described, but doesn't generalize to nested objects, etc.)