pass JSON to HTTP POST Request

Jsonnode.jsCurlExpressNode Request

Json Problem Overview


I'm trying to make a HTTP POST request to the google QPX Express API [1] using nodejs and request [2].

My code looks as follows:

    // create http request client to consume the QPX API
    var request = require("request")

    // JSON to be passed to the QPX Express API
    var requestData = {
        "request": {
            "slice": [
                {
                    "origin": "ZRH",
                    "destination": "DUS",
                    "date": "2014-12-02"
                }
            ],
            "passengers": {
                "adultCount": 1,
                "infantInLapCount": 0,
                "infantInSeatCount": 0,
                "childCount": 0,
                "seniorCount": 0
            },
            "solutions": 2,
            "refundable": false
        }
    }

    // QPX REST API URL (I censored my api key)
    url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=myApiKey"

    // fire request
    request({
        url: url,
        json: true,
        multipart: {
            chunked: false,
            data: [
                {
                    'content-type': 'application/json',
                    body: requestData
                }
            ]
        }
    }, function (error, response, body) {
        if (!error && response.statusCode === 200) {
            console.log(body)
        }
        else {

            console.log("error: " + error)
            console.log("response.statusCode: " + response.statusCode)
            console.log("response.statusText: " + response.statusText)
        }
    })

What I'm trying to do is passing the JSON using the multipart argument [3]. But instead of the proper JSON response I got an error (400 undefined).

When I make a request using the same JSON and API Key using CURL instead, it works fine. So there's nothing wrong with my API key or JSON.

What's wrong with my code?

EDIT:

working CURL example:

i) I saved the JSON which I would pass to my request into a file called "request.json":

{
  "request": {
    "slice": [
      {
        "origin": "ZRH",
        "destination": "DUS",
        "date": "2014-12-02"
      }
    ],
    "passengers": {
      "adultCount": 1,
      "infantInLapCount": 0,
      "infantInSeatCount": 0,
      "childCount": 0,
      "seniorCount": 0
    },
    "solutions": 20,
    "refundable": false
  }
}

ii) then, in the terminal I switched to the directory in which the newly created request.json file was located and run (myApiKey stands for my actual API Key obviously):

curl -d @request.json --header "Content-Type: application/json" https://www.googleapis.com/qpxExpress/v1/trips/search?key=myApiKey

[1] https://developers.google.com/qpx-express/ [2] a http request client designed for nodejs: https://www.npmjs.org/package/request [3] here is an example I found https://www.npmjs.org/package/request#multipart-related [4] https://stackoverflow.com/questions/27179248/qpx-express-api-is-returning-400-parse-error

Json Solutions


Solution 1 - Json

I think the following should work:

// fire request
request({
    url: url,
    method: "POST",
    json: requestData
}, ...

In this case, the Content-type: application/json header is automatically added.

Solution 2 - Json

I worked on this for too long. The answer that helped me was at: https://stackoverflow.com/questions/8675688/send-content-type-application-json-post-with-node-js

Which uses the following format:

request({
	url: url,
	method: "POST",
	headers: {
		"content-type": "application/json",
		},
	json: requestData
//	body: JSON.stringify(requestData)
	}, function (error, resp, body) { ...

Solution 3 - Json

You don't want multipart, but a "plain" POST request (with Content-Type: application/json) instead. Here is all you need:

var request = require('request');

var requestData = {
  request: {
    slice: [
      {
        origin: "ZRH",
        destination: "DUS",
        date: "2014-12-02"
      }
    ],
    passengers: {
      adultCount: 1,
      infantInLapCount: 0,
      infantInSeatCount: 0,
      childCount: 0,
      seniorCount: 0
    },
    solutions: 2,
    refundable: false
  }
};

request('https://www.googleapis.com/qpxExpress/v1/trips/search?key=myApiKey',
        { json: true, body: requestData },
        function(err, res, body) {
  // `body` is a js object if request was successful
});

Solution 4 - Json

Now with new JavaScript version (ECMAScript 6 http://es6-features.org/#ClassDefinition) there is a better way to submit requests using nodejs and Promise request (http://www.wintellect.com/devcenter/nstieglitz/5-great-features-in-es6-harmony)

Using library: https://github.com/request/request-promise

npm install --save request
npm install --save request-promise

client:

//Sequential execution for node.js using ES6 ECMAScript
var rp = require('request-promise');

rp({
    method: 'POST',
    uri: 'http://localhost:3000/',
    body: {
        val1 : 1,
        val2 : 2
    },
    json: true // Automatically stringifies the body to JSON
}).then(function (parsedBody) {
        console.log(parsedBody);
        // POST succeeded...
    })
    .catch(function (err) {
        console.log(parsedBody);
        // POST failed...
    });

server:

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

var app = express();

app.use(bodyParser.json());

app.post('/', function(request, response){
    console.log(request.body);      // your JSON

    var jsonRequest = request.body;
    var jsonResponse = {};

    jsonResponse.result = jsonRequest.val1 + jsonRequest.val2;

    response.send(jsonResponse);
});


app.listen(3000);

Solution 5 - Json

Example.

var request = require('request');

var url = "http://localhost:3000";

var requestData = {
    ...
} 

var data = {
    url: url,
    json: true,
    body: JSON.stringify(requestData)
}

request.post(data, function(error, httpResponse, body){
    console.log(body);
});

As inserting json: true option, sets body to JSON representation of value and adds "Content-type": "application/json" header. Additionally, parses the response body as JSON. LINK

Solution 6 - Json

According to doc: https://github.com/request/request

The example is:

  multipart: {
      chunked: false,
      data: [
        {
          'content-type': 'application/json', 
          body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})
        },
      ]
    }

I think you send an object where a string is expected, replace

body: requestData

by

body: JSON.stringify(requestData)

Solution 7 - Json

       var request = require('request');
        request({
            url: "http://localhost:8001/xyz",
            json: true,
            headers: {
                "content-type": "application/json",
            },
            body: JSON.stringify(requestData)
        }, function(error, response, body) {
            console.log(response);
        });

Solution 8 - Json

I feel

var x = request.post({
       uri: config.uri,
       json: reqData
    });

Defining like this will be the effective way of writing your code. And application/json should be automatically added. There is no need to specifically declare it.

Solution 9 - Json

you can pass the json object as the body(third argument) of the fetch request.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRoninView Question on Stackoverflow
Solution 1 - JsonTobiView Answer on Stackoverflow
Solution 2 - JsonDanBakerView Answer on Stackoverflow
Solution 3 - JsonmscdexView Answer on Stackoverflow
Solution 4 - JsonEvalds UrtansView Answer on Stackoverflow
Solution 5 - JsonYoungmin KimView Answer on Stackoverflow
Solution 6 - JsonBaartView Answer on Stackoverflow
Solution 7 - JsonAshish GuptaView Answer on Stackoverflow
Solution 8 - JsonSidd ThotaView Answer on Stackoverflow
Solution 9 - Jsonankur tiwariView Answer on Stackoverflow