I'm attempting to do a direct integration between AWS API Gateway and AWS Eventbridge by using the AWSIntegration
cdk class. Each request to the API Gateway endpoint should emit an event to the Eventbridge.
Here's a sample incoming JSON request body to the gateway:
{
"id": "5c5d0e79-b808-4d85-b765-b2b45125a72c",
"subscriber": {
"id": "595be504-9c29-4584-8e76-c7651cd5202e"
},
"event": {
"header": {
"id": "fd884d88-c8fa-4084-9edc-65d34187bdde",
"occurredOn": "2023-04-18T20:51:40.170Z",
"eventType": {
"key": "my.event.type",
"name": "my.event.type"
},
"publisher": {
"id": "cc5f5916-5cf8-4032-bd81-85817a51aec0",
"key": "publisher-environment-key",
"tags": [
{
"name": "my.item.guid",
"value": "18888872-991b-4dfd-9754-19219b8b8665"
},
{
"name": "my.item.key",
"value": "special-service"
}
]
}
}
}
}
I then want to emit an event with the following attributes from the input:
DetailType: "my.event.type",
Source: "my.item.key",
Detail: "...", // the whole payload that came into the gateway
The event is being emitted, but I'm struggling with my JSONPath syntax to pull values from the input. I believe because I'm trying to match against a value with .
characters in it.
Here's the current requestTemplates
property:
requestTemplates: {
'application/json': `
#set($context.requestOverride.header.X-Amz-Target ="AWSEvents.PutEvents")
#set($context.requestOverride.header.Content-Type ="application/x-amz-json-1.1")
${JSON.stringify({
Entries: [
{
DetailType: `$input.path('$.event.header.eventType.key')`,
Source: `$input.path('$.event.header.publisher.tags[?(@.name==my.item.key)].value')`,
Detail: "$util.escapeJavaScript($input.json('$'))",
EventBusName: eventBus.eventBusArn,
},
],
})}
`
The DetailType
property is set correctly but I get an empty value for the Source
property. I've tried wrapping my.item.key
in single and double quotes as well as attempting to escape the periods but with no luck. Is there a way I can pull that value by matching on the name
property?
I don't really want to access via the array index because its possible it could be in different orders.
Answering for any who run into the same problem. I was able to solve this by leveraging Apache VTL in the template.
By moving the property I needed into a VTL variable, I was then able to use array manipulation to get the value that I needed.
First set the value into a VTL variable:
#set($publisherTags=$input.path('$.event.header.publisher.tags[?(@.name==my.item.key)]')
Now that the specific value of the array is in a VTL variable use array indexing and get the value. In this case the index can be used because in step one we limited down by one of the properties in the object within the array.
Source: `$publisherTags[0].value`