0

I'm trying to publish an event to AWS Event Bridge via an API Gateway while transforming the event body using API gateway mapping templates written in Velocity Template Language (VLT) following this guide.

The event body looks like this

{
    "ordersDelivered": [
        {
            "orderId": "a0874e2c-4ad3-4fda-8145-18cc51616ecd",
            "address": {
                "line2": "10 Broad Road",
                "city": "Altrincham",
                "zipCode": "WA15 7PC",
                "state": "Cheshire",
                "country": "United Kingdom"
            }
        }
    ]
}

and the VLT template like

#set($context.requestOverride.header.X-Amz-Target = "AWSEvents.PutEvents")
#set($context.requestOverride.header.Content-Type = "application/x-amz-json-1.1")

#set($inputRoot = $input.path('$'))
{
"Entries": [
    #foreach($elem in $inputRoot.ordersDelivered)
    {
        "Resources" : ["$context.authorizer.clientId"],
        "Detail" : "$util.escapeJavaScript($elem)",
        "DetailType" : "OrderDelivered",
        "EventBusName" : "hk-playground-more-sole",
        "Source" : "delivery"
    }#if($foreach.hasNext),#end
    #end
]
}

However on making a test call to the REST endpoint method via the API Gateway 'Test' option in the AWS console, I get a malformed request error from the EventBridge integration as shown below:

Endpoint request body after transformations: 
{
"Entries": [
        {
        "Resources" : [""],
        "Detail" : "{orderId=a0874e2c-4ad3-4fda-8145-18cc51616ecd, address={line2=10 Broad Road, city=Altrincham, zipCode=WA15 7PC, state=Cheshire, country=United Kingdom}}",
        "DetailType" : "OrderDelivered",
        "EventBusName" : "hk-playground-more-sole",
        "Source" : "delivery"
    }    ]
}

Sending request to https://events.{aws-region}.amazonaws.com/?Action=PutEvents
Received response. Status: 200, Integration latency: 32 ms
Endpoint response headers: {x-amzn-RequestId=6cd086bf-5147-4418-9498-b467ed2b6b58, Content-Type=application/x-amz-json-1.1, Content-Length=104, Date=Thu, 15 Sep 2022 10:17:44 GMT}
Endpoint response body before transformations: {"Entries":[{"ErrorCode":"MalformedDetail","ErrorMessage":"Detail is malformed."}],"FailedEntryCount":1}
Method response body after transformations: {"Entries":[{"ErrorCode":"MalformedDetail","ErrorMessage":"Detail is malformed."}],"FailedEntryCount":1}

The logs above suggest that $elem object is not being converted to JSON, so instead of $util.escapeJavaScript($elem) I tried using $util.toJson($elem) but that assigns an empty string to the Detail element and I get a 400 error. I have also tried to change the VLT template to directly read the ordersDelivered using JSONPath expression string

#set($inputRoot = $input.path('$.ordersDelivered'))
{
"Entries": [
    #foreach($elem in $inputRoot)
    {
        "Resources" : ["$context.authorizer.clientId"],
        "Detail" : "$util.escapeJavaScript($elem)",
        "DetailType" : "OrderDelivered",
        "EventBusName" : "hk-playground-more-sole",
        "Source" : "delivery"
    }#if($foreach.hasNext),#end
    #end
]
}

but I still get the same MalformedDetail error as above on testing this. Am I missing the correct way of converting JSON in the Detail element?

Hemant
  • 41
  • 1
  • 5

0 Answers0