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 answers

2
Adam Wiggall 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
Christian Bongiorno 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
nondescript 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>`"