There does not seem to be much documentation on this, and most of the other questions don't appear to be as complete.
I would like to reliably transform a json object that hits my API Gateway endpoint into application/x-www-form-urlencoded
so that I may pass it into an SQS queue.
So far I have tried every available option I could find online:
This method above produces the following body after transformation:
MessageBody=%7B%22event_type%22%3A%22click%22%2C%22click_time%22%3A%222023-10-17T00%3A55%3A04Z%22%2C%22user_agent%22%3A%22Mozilla%2F5.0%20(iPhone%3B%20CPU%20iPhone%20OS%2016_3_1%20like%20Mac%20OS%20X)%20AppleWebKit%2F605.1.15%20(KHTML%2C%20like%20Gecko)%20Version%2F16.3%20Mobile%2F15E148%20Safari%2F604.1%22%7D&Action=SendMessage
Which produced a result similar to the one above.
In both cases, the same error was thrown within api gateway:
Received response. Status: 404, Integration latency
And a few lines further down:
Endpoint response body before transformations: <UnknownOperationException/>
I even tried to do some fancy mapping template stuff, that just didn't work (maybe you can spot the error(s) in this:
#set($inputJson = $input.body)
#set($urlEncodedParams = "")
#foreach($key in $inputJson.keySet())
#set($value = $inputJson.get($key))
#if($foreach.hasNext)
#set($urlEncodedParams = "$urlEncodedParams${esc.url($key)}=${esc.url($value)}&")
#else
#set($urlEncodedParams = "$urlEncodedParams${esc.url($key)}=${esc.url($value)}")
#end
#end
MessageBody=$urlEncodedParams&Action=SendMessage
Note: I currently have no content-type headers set, it is open as that endpoint will receive both urlencoded and json data, relying on the correct mapping template to pick it up.
Please contribute what you can, I feel like this could help many people over time if solved reliably.
Ethan
TLDR: I want to transform JSON data hitting my api gateway into a x-www-form-encoded so I can forward it to my SQS Queue.
Before (passed in):
{
"event_type": "click",
"click_time": "2023-10-16T22:39:59Z",
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Mobile/15E148 Safari/604.1"
}
After (passed to SQS):
MessageBody=event_type%3Dclick%26click_time%3D2023-10-16T22%3A39%3A59Z%26user_agent%3DMozilla%2F5.0%20%28iPhone%3B%20CPU%20iPhone%20OS%2016_3_1%20like%20Mac%20OS%20X%29%20AppleWebKit%2F605.1.15%20%28KHTML%2C%20like%20Gecko%29%20Version%2F16.3%20Mobile%2F15E148%20Safari%2F604.1&Action=SendMessage
Update 2:
When I switch to a native integration like shown below, I get this error: {"Error":{"Code":"AWS.SimpleQueueService.NonExistentQueue","Message":"The specified queue does not exist for this wsdl version...
Checking cloudwatch, I see:
Sending request to https://sqs.us-east-1.amazonaws.com/?Action=SendMessage
Obviously, that's missing the path to the actual Queue, even though I include it in the request body after transformations:
{
"MessageBody": "{\"event_type\":\"click\"}",
"QueueUrl": "https://sqs.us-east-1.amazonaws.com/..."
}
Previously, I set action type to Use Path Override
where I was able to put the Queue url directly like so:
{ACCOUNTID}/{QUEUE-PATH}
This worked, but not with the mapping templates below.
You don't need to use
application/x-www-form-urlencoded
to call SQS, JSON works fine.X-Amz-Target
:'AmazonSQS.SendMessage'
Content-Type
:'application/x-amz-json-1.0'
application/json
:This also serves as poor man's validation: if your input is not valid JSON, the endpoint will fail.
If you have proper validation in place, or if you don't care if the JSON is well-formed, you can simplify it a little bit: