0

I am trying to print JSON object i.e. req.body in NodeJS using the below commands, but using JSON.stringify doesn't help. Could someone please suggest/guide how I can print this JSON object req.body

  console.log("printing body: "+JSON.stringify(req.body))
  console.log("printing body: "+req.body)
  console.log("printing headers: "+JSON.stringify(req.headers))

Output:

printing body: {}
printing body: [object Object]
printing headers: {
    "x-amz-sns-message-type": "SubscriptionConfirmation",
    "x-amz-sns-message-id": "3dd623ert-7203-4e12-bf11-36589f9dce65",
    "x-amz-sns-topic-arn": "arn:aws:sns:us-west-2:33030356879323:testTopic10",
    "content-length": "1520",
    "content-type": "text/plain; charset=UTF-8",
    "host": "example.com",
    "connection": "Keep-Alive",
    "user-agent": "Amazon Simple Notification Service Agent",
    "accept-encoding": "gzip,deflate"
}

Guidelines to Parse the JSON Object given by Amazon SNS:

In step 1: Point 2 of this document it advises

Use a JSON parser that handles converting the escaped representation of control characters back to their ASCII character values (for example, converting \n to a newline character). You can use an existing JSON parser such as the Jackson JSON Processor (http://wiki.fasterxml.com/JacksonHome) or write your own.

EDIT 1:

As you may see the printed headers, they have content-type": "text/plain; charset=UTF-8, could this be the reason why the bodyparser.json() doesn't work and we are unable to use JSON.stringify()

EDIT 2

Here is my body parsing code.

var bodyParser    = require('body-parser');

app.use(bodyParser.json()); // Used to parse the JSON request
app.use(bodyParser.urlencoded({ extended: true }));

EDIT 3:

SAMPLE OF THE RAW BODY THAT IS SENT IN THE REQUEST

{
  "Type" : "SubscriptionConfirmation",
  "MessageId" : "4c3232a-f297-4fba-96e8-dc821a0b2621",
  "Token" : "2336412f37fb687f5d51e6e241d59b68c4e23a8e1a7b89aecf0dd7e227b0cf8ce107c9d1a4216d1aaf7dcdf66c18f0e06f1811a98351ced5018395453fee6f7e12fd5962220e0a81431063914e7b8d0c5340baeaf9dd2fe12e5288fbb88405fca2136c026d2b04e709e8ab6",
  "TopicArn" : "arn:aws:sns:us-west-2:3303035234123:testTopic10",
  "Message" : "You have chosen to subscribe to the topic arn:aws:sns:us-west-2:33030123453:testTopic10.\nTo confirm the subscription, visit the SubscribeURL included in this message.",
  "SubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:33030234243413:testTopic10&Token=2336412f37fb687f5d51e6e241d59b68c4e58148956199a8e1a7be0dd7e227b0cfer1aaf7dcdf66c18f0e06f1811a98351ced5018395453fee6f7e12fd5962220e0a81431063914e7b8d0c5340baeaf9dd2fe12e5288fbb88405fca2136c026d2b04e709e8ab6",
  "Timestamp" : "2017-09-04T13:06:36.005Z",
  "SignatureVersion" : "1",
  "Signature" : "QRy9574PIfSuNReyGEgDO86/utgF7R5enCmQTYBsUIdN0ohF9jWzh+qU9FLDp7EIXzg6Q3bLoI3HeYzNE4iMLHATixf2Iz29e0/ekWaMBewj+Q+pt42tKDh9YndRmyE2CSRJ7LTnvTVpS3MUgDI/kaQKmThxgN9wb8y8gebojuIE6zNAbYmuVVA+W6rIiF+dyG9e+f89dWSSReITB19XaVtLZ/BrcQWRyrBRFE06lXxYuGaLUIfTvItleaxX/BxKnNdxUL04sRNQ==",
  "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-433026a4050d206028891123453da859041.pem"
}
kurrodu
  • 2,108
  • 4
  • 32
  • 49
  • What doesn't work? In your example `req.body` is an empty object. – alexmac Sep 04 '17 at 08:44
  • `console.log` accepts several arguments. If you call it like `console.log('printing body, req.body)`, you'll get the full object written to stdout. But as @alexmac mentions, it looks like `req.body` is empty – Kris Selbekk Sep 04 '17 at 08:44
  • possible duplicate: https://stackoverflow.com/questions/10729276/how-can-i-get-the-full-object-in-node-jss-console-log-rather-than-object – Raghav Garg Sep 04 '17 at 08:44
  • that's weird, it should output what you want. Are you sure `req.body` has any data? – Shinra tensei Sep 04 '17 at 08:45
  • @alexmac please read the edit in my question. – kurrodu Sep 04 '17 at 13:56
  • what are you using to parse the body? [https://www.npmjs.com/package/body-parser](https://www.npmjs.com/package/body-parser#bodyparsertextoptions) works well for this and can parse the plain-text content-type [https://www.npmjs.com/package/body-parser#bodyparsertextoptions](https://www.npmjs.com/package/body-parser#bodyparsertextoptions) – Sello Mkantjwa Sep 04 '17 at 14:01
  • @SelloMkantjwa please see my edit 2 – kurrodu Sep 04 '17 at 14:05
  • 1
    Try adding `app.use(bodyParser.text({type:"text/plain"}))` after `app.use(bodyParser.urlencoded({ extended: true }));` I think that's the way to add support for text/plain content. See [here](https://www.npmjs.com/package/body-parser#bodyparsertextopti‌​ons) – Sello Mkantjwa Sep 04 '17 at 14:08
  • @SelloMkantjwa it still doesn't print `req.body` – kurrodu Sep 04 '17 at 14:21
  • What does the body that you post through look like? – Sello Mkantjwa Sep 04 '17 at 14:21
  • @SelloMkantjwa added in Edit 3 – kurrodu Sep 04 '17 at 14:27
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/153621/discussion-between-sello-mkantjwa-and-kurrodu). – Sello Mkantjwa Sep 04 '17 at 14:34
  • It would be more productive if all the developers demanded that AWS fix this bullshit they did. [A bullshit officially documented 6 years ago](https://forums.aws.amazon.com/thread.jspa?threadID=69413#262098). – TaoTao Dec 13 '17 at 20:27

2 Answers2

2

JSON.stringify() did print out the object. The object is just empty, i.e {}.

Sello Mkantjwa
  • 1,798
  • 1
  • 20
  • 36
0

There's a built-in solution in Amazon SNS for it now. Amazon SNS just launched support for custom Content-Type headers for HTTP messages delivered from topics. Here's the launch post: https://aws.amazon.com/about-aws/whats-new/2023/03/amazon-sns-content-type-request-headers-http-s-notifications/

You'll have to modify the DeliveryPolicy attribute of your Amazon SNS subscription, setting the headerContentType property to application/json, or any other value supported. You can find all values supported here: https://docs.aws.amazon.com/sns/latest/dg/sns-message-delivery-retries.html#creating-delivery-policy

{
    "healthyRetryPolicy": {
        "minDelayTarget": 1,
        "maxDelayTarget": 60,
        "numRetries": 50,
        "numNoDelayRetries": 3,
        "numMinDelayRetries": 2,
        "numMaxDelayRetries": 35,
        "backoffFunction": "exponential"
    },
    "throttlePolicy": {
        "maxReceivesPerSecond": 10
    },
    "requestPolicy": {
        "headerContentType": "application/json"
    }
}

You set the DeliveryPolicy attribute by calling either the Subscribe or the SetSubscriptionAttributes API action:

Alternatively, you can use AWS CloudFormation for setting this policy as well, using the AWS::SNS::Subscription resource.

Otavio Ferreira
  • 755
  • 6
  • 11