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!