How do I POST a JSON file as MessageBody for Amazon SQS?

12k Views Asked by At

I run ElasticMQ locally to emulate Amazon SQS, and I want to send a JSON file as a MessageBody. Here's an example request that works:

$ curl 'http://localhost:9324/queue/foo?Action=SendMessage&MessageBody={"action":"hey"}'

<SendMessageResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
          <SendMessageResult>
              [...]

If I want to send a large JSON file, it would make more sense to to that as a POST, something like this:

$ curl 'http://localhost:9324/queue/foo?Action=SendMessage' -X POST \
     -H "Content-Type: application/json" --data @./bigdata.json

There was an internal server error.

Is there a way to make this work?

3

There are 3 best solutions below

2
On BEST ANSWER

This is an old one now, but I've recently fell short on this and wanted to add in what I've found.

If you set the Content-Type to text/plain the message succeeds, which is so counter intuitive with a json data payload.

$ curl -X "POST" "https://sqs.us-east-1.amazonaws.com/136525823465/rfidsqs?Action=SendMessage" -H 'Content-Type: text/plain' -d '{"testKey1": 123456,"testKey2": "5sUXJYodEUVvQwVT"}'

Reponse

<SendMessageResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
  <SendMessageResult>
    <MessageId>ba2f6498-0e6b-48cd-bd8f-027d911082b6</MessageId>
    <MD5OfMessageBody>4c8132a52a4e6f0bb5ecbe758502c69f</MD5OfMessageBody>
  </SendMessageResult>
  <ResponseMetadata>
    <RequestId>ddc02593-8757-5d0b-a780-72183ae5f517</RequestId>
  </ResponseMetadata>
</SendMessageResponse>
0
On

I don't think it's possible. Based on the documentation and experimentation the only content-type it accepts is form application/x-www-form-urlencoded which means that the body can only have key=value pairs. You could have to supply a value that was the actual JSON body

cbongiorno at wa-christianb-mbp in ~/dev/core-infra on anchore-update [+!$]
$  curl -H "content-type: application/json" -d '{"id":123}' https://sqs.us-east-1.amazonaws.com/123456789/christian-anchore-test?Action=SendMessage | xmllint --format -
<?xml version="1.0"?>
<ErrorResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
  <Error>
    <Type>Sender</Type>
    <Code>MissingParameter</Code>
    <Message>The request must contain the parameter MessageBody.</Message>
    <Detail/>
  </Error>
  <RequestId>9452510a-0a40-5f68-8319-05cf9ed70beb</RequestId>
</ErrorResponse>

This seems like a heinously short-sighted decision but as you can tell from the params accepted there is just 1 URL and it's used as a control signal URL. It's very SOAP like but in a custom/hacked crap sort-of a way.

I have the same struggle now. Depending on what you're trying to do you can create a private API gateway and hookup a lambda to remap it. But no matter how you slice it, you MUST remap it

0
On

this works for me

aws  --endpoint-url http://localhost:9324 sqs send-message --queue-url http://localhost:9324/000000000000/<your queue>  --message-body "`cat ./<yourjsonfile.json>`"