Brief:
I have an API Gateway(V1-RestAPI) that sends events to EventBrdige on HTTP calls. I would like to put an event into EventBridge using the basic template of API Gateway - Method Request Passthrough in the following way:
Entries: [{
Detail: { Data: <Method Request Passthrough Template>, MetaData {<Whatever> }},
Source: <...>,
DetailType: <...>,
EventBusName: <...>
}]
In order to do so, I have to use both
#set($context.requestOverride.header.X-Amz-Target = "AWSEvents.PutEvents")
#set($context.requestOverride.header.Content-Type = "application/x-amz-json-1.1")
The Problem:
My issue is that x-amz-json/EventBridge requires to escape characters inside the Detail Json, which isn't very fun.
If I try to use
Detail: $util.escapeJavaScript({Data: ...})
it won't work because there's a usage of #foreach inside the template, and stringifying it won't do any good.
For example:
#foreach($type in $allParams.keySet())
#set($params = $allParams.get($type)) ...
So far, I have managed to make it work only by using a very ugly solution in which I escaped the characters manually. I would like to find a way to make it look decent and "Editable" by other people.
Here is the VTL - Doesn't work but looks good
#set($context.requestOverride.header.X-Amz-Target = "AWSEvents.PutEvents")
#set($context.requestOverride.header.Content-Type = "application/x-amz-json-1.1")
#set($allParams = $input.params())
{
"Entries": [
{
"Detail": {
"Data": {
"body-json" : $util.escapeJavaScript($input.json('$')),
"params" : {
#foreach($type in $allParams.keySet())
#set($params = $allParams.get($type))
"$type" : {
#foreach($paramName in $params.keySet())
"$paramName" : "$util.escapeJavaScript($params.get($paramName))"
#if($foreach.hasNext),#end
#end
}
#if($foreach.hasNext),#end
#end
},
"stage-variables" : {
#foreach($key in $stageVariables.keySet())
"$key" : "$util.escapeJavaScript($stageVariables.get($key))"
#if($foreach.hasNext),#end
#end
},
"context" : {
"account-id" : "$context.identity.accountId",
"api-id" : "$context.apiId",
"api-key" : "$context.identity.apiKey",
"authorizer-principal-id" : "$context.authorizer.principalId",
"caller" : "$context.identity.caller",
"cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider",
"cognito-authentication-type" : "$context.identity.cognitoAuthenticationType",
"cognito-identity-id" : "$context.identity.cognitoIdentityId",
"cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId",
"http-method" : "$context.httpMethod",
"stage" : "$context.stage",
"source-ip" : "$context.identity.sourceIp",
"user" : "$context.identity.user",
"user-agent" : "$context.identity.userAgent",
"user-arn" : "$context.identity.userArn",
"request-id" : "$context.requestId",
"resource-id" : "$context.resourceId",
"resource-path" : "$context.resourcePath"
}
},
"MetaData": {}
},
"DetailType": "FILL-NAME",
"EventBusName": "$stageVariables.eventBus",
"Source": "ClientRequest"
}
]
}
And here is the escaped detail version that looks like hell, but works
{ \n \"Data\": {\n \"body-json\" : $util.escapeJavaScript($input.json('$')),\n \"params\" : {\n #foreach($type in $allParams.keySet())\n #set($params = $allParams.get($type))\n \"$type\" : {\n #foreach($paramName in $params.keySet())\n \"$paramName\" : \"$util.escapeJavaScript($params.get($paramName))\"\n #if($foreach.hasNext),#end\n #end\n }\n #if($foreach.hasNext),#end\n #end\n },\n \"stage-variables\" : {\n #foreach($key in $stageVariables.keySet())\n \"$key\" : \"$util.escapeJavaScript($stageVariables.get($key))\"\n #if($foreach.hasNext),#end\n #end\n },\n \"context\" : {\n \"account-id\" : \"$context.identity.accountId\",\n \"api-id\" : \"$context.apiId\",\n \"api-key\" : \"$context.identity.apiKey\",\n \"authorizer-principal-id\" : \"$context.authorizer.principalId\",\n \"caller\" : \"$context.identity.caller\",\n \"cognito-authentication-provider\" : \"$context.identity.cognitoAuthenticationProvider\",\n \"cognito-authentication-type\" : \"$context.identity.cognitoAuthenticationType\",\n \"cognito-identity-id\" : \"$context.identity.cognitoIdentityId\",\n \"cognito-identity-pool-id\" : \"$context.identity.cognitoIdentityPoolId\",\n \"http-method\" : \"$context.httpMethod\",\n \"stage\" : \"$context.stage\",\n \"source-ip\" : \"$context.identity.sourceIp\",\n \"user\" : \"$context.identity.user\",\n \"user-agent\" : \"$context.identity.userAgent\",\n \"user-arn\" : \"$context.identity.userArn\",\n \"request-id\" : \"$context.requestId\",\n \"resource-id\" : \"$context.resourceId\",\n \"resource-path\" : \"$context.resourcePath\"\n }\n },\n \"MetaData\": {}\n }
As I'm not a professional in VTL or anything of that sort, if anyone has any insight as to how this can be solved, it would be awesome!
Solved it by using variables outside of the directive scope.