218

In Node.js, other than using child process to make CURL call, is there a way to make CURL call to remote server REST API and get the return data?

I also need to set up the request header to the remote REST call, and also query string as well in GET (or POST).

I find this one: http://blog.nodejitsu.com/jsdom-jquery-in-5-lines-on-nodejs

but it doesn't show any way to POST query string.

alex
  • 479,566
  • 201
  • 878
  • 984
murvinlai
  • 48,919
  • 52
  • 129
  • 177

15 Answers15

238

Look at http.request

var options = {
  host: url,
  port: 80,
  path: '/resource?id=foo&bar=baz',
  method: 'POST'
};

http.request(options, function(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));
  res.setEncoding('utf8');
  res.on('data', function (chunk) {
    console.log('BODY: ' + chunk);
  });
}).end();
Scott Stensland
  • 26,870
  • 12
  • 93
  • 104
Raynos
  • 166,823
  • 56
  • 351
  • 396
  • 3
    So, even it is POST, I also append data in the query string? – murvinlai Apr 13 '11 at 18:28
  • 3
    @murvinlai not sure. Go read the docs, source, HTTP spec. Not an expert on that region. – Raynos Apr 13 '11 at 19:09
  • Version 6.18 docs : http://nodejs.org/docs/v0.6.18/api/http.html#http_http_request_options_callback – weisjohn Jun 15 '12 at 14:58
  • 18
    One thing to note is that you don't put http or https in your host entry e.g. var options = { host: graph.facebook.com .... } not {host: http: graph.facebook.com }. That tripped me up for a few cycles. (See below). These are both great answers. Thanks to you both. – binarygiant Mar 07 '13 at 21:00
  • 10
    Can I just point out that if the reply is long, using res.on('data',..) is not enough. I believe the correct way is to also have res.on('end'..) to know when you have received all the data. Then you can process. – Xerri Mar 26 '13 at 11:18
  • 4
    This is a very old answer - for those writing node js today you'd surely use https://www.npmjs.com/package/node-fetch or other fetch API based package, which is based on the Fetch standard. See my answer below. – saille Oct 05 '16 at 01:14
  • 3
    Could you mention how you called the http module? require('WHAT?') – user3072843 Sep 21 '17 at 19:28
  • @user3072843, it's there in the link mentioned. require('node-fetch'); – CodeMad Nov 20 '17 at 12:28
97

How about using Request — Simplified HTTP client.

Edit February 2020: Request has been deprecated so you probably shouldn't use it any more.

Here's a GET:

var request = require('request');
request('http://www.google.com', function (error, response, body) {
    if (!error && response.statusCode === 200) {
        console.log(body) // Print the google web page.
     }
})

OP also wanted a POST:

request.post('http://service.com/upload', {form:{key:'value'}})
Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
Matt Frear
  • 52,283
  • 12
  • 78
  • 86
52

I use node-fetch because it uses the familiar (if you are a web developer) fetch() API. fetch() is the new way to make arbitrary HTTP requests from the browser.

Yes I know this is a node js question, but don't we want to reduce the number of API's developers have to memorize and understand, and improve re-useability of our javascript code? Fetch is a standard so how about we converge on that?

The other nice thing about fetch() is that it returns a javascript Promise, so you can write async code like this:

let fetch = require('node-fetch');

fetch('http://localhost', {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: '{}'
}).then(response => {
  return response.json();
}).catch(err => {console.log(err);});

Fetch superseeds XMLHTTPRequest. Here's some more info.

Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
saille
  • 9,014
  • 5
  • 45
  • 57
  • problem with `node-fetch` when writting APIs is that only works will full URL and will not work with relative URLs. – Sebastian Aug 26 '18 at 03:49
  • 1
    Note: fetch() is coming to the core NodeJS runtime as of v17.5 https://fusebit.io/blog/node-fetch/ – saille Feb 03 '22 at 21:20
41

Look at http://isolasoftware.it/2012/05/28/call-rest-api-with-node-js/

var https = require('https');

/**
 * HOW TO Make an HTTP Call - GET
 */
// options for GET
var optionsget = {
    host : 'graph.facebook.com', // here only the domain name
    // (no http/https !)
    port : 443,
    path : '/youscada', // the rest of the url with parameters if needed
    method : 'GET' // do GET
};

console.info('Options prepared:');
console.info(optionsget);
console.info('Do the GET call');

// do the GET request
var reqGet = https.request(optionsget, function(res) {
    console.log("statusCode: ", res.statusCode);
    // uncomment it for header details
    // console.log("headers: ", res.headers);

    res.on('data', function(d) {
        console.info('GET result:\n');
        process.stdout.write(d);
        console.info('\n\nCall completed');
    });

});

reqGet.end();
reqGet.on('error', function(e) {
    console.error(e);
});

/**
 * HOW TO Make an HTTP Call - POST
 */
// do a POST request
// create the JSON object
jsonObject = JSON.stringify({
    "message" : "The web of things is approaching, let do some tests to be ready!",
    "name" : "Test message posted with node.js",
    "caption" : "Some tests with node.js",
    "link" : "http://www.youscada.com",
    "description" : "this is a description",
    "picture" : "http://youscada.com/wp-content/uploads/2012/05/logo2.png",
    "actions" : [ {
        "name" : "youSCADA",
        "link" : "http://www.youscada.com"
    } ]
});

// prepare the header
var postheaders = {
    'Content-Type' : 'application/json',
    'Content-Length' : Buffer.byteLength(jsonObject, 'utf8')
};

// the post options
var optionspost = {
    host : 'graph.facebook.com',
    port : 443,
    path : '/youscada/feed?access_token=your_api_key',
    method : 'POST',
    headers : postheaders
};

console.info('Options prepared:');
console.info(optionspost);
console.info('Do the POST call');

// do the POST call
var reqPost = https.request(optionspost, function(res) {
    console.log("statusCode: ", res.statusCode);
    // uncomment it for header details
//  console.log("headers: ", res.headers);

    res.on('data', function(d) {
        console.info('POST result:\n');
        process.stdout.write(d);
        console.info('\n\nPOST completed');
    });
});

// write the json data
reqPost.write(jsonObject);
reqPost.end();
reqPost.on('error', function(e) {
    console.error(e);
});

/**
 * Get Message - GET
 */
// options for GET
var optionsgetmsg = {
    host : 'graph.facebook.com', // here only the domain name
    // (no http/https !)
    port : 443,
    path : '/youscada/feed?access_token=you_api_key', // the rest of the url with parameters if needed
    method : 'GET' // do GET
};

console.info('Options prepared:');
console.info(optionsgetmsg);
console.info('Do the GET call');

// do the GET request
var reqGet = https.request(optionsgetmsg, function(res) {
    console.log("statusCode: ", res.statusCode);
    // uncomment it for header details
//  console.log("headers: ", res.headers);


    res.on('data', function(d) {
        console.info('GET result after POST:\n');
        process.stdout.write(d);
        console.info('\n\nCall completed');
    });

});

reqGet.end();
reqGet.on('error', function(e) {
    console.error(e);
});
Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
Giulio Roggero
  • 1,692
  • 1
  • 16
  • 11
  • 1
    How do i access the values from d??? d = {"data":[{"id":1111,"name":"peter"}]} . how to get name value? – peter Feb 18 '13 at 12:58
  • 2
    managed to get values by using var thed = JSON.parse(d); console.log("the id is : "+thed.data[0].id); But some time i get "Unexpected end of input" – peter Feb 19 '13 at 07:52
19

Axios

An example (axios_example.js) using Axios in Node.js:

const axios = require('axios');
const express = require('express');
const app = express();
const port = process.env.PORT || 5000;

app.get('/search', function(req, res) {
    let query = req.query.queryStr;
    let url = `https://your.service.org?query=${query}`;

    axios({
        method:'get',
        url,
        auth: {
            username: 'the_username',
            password: 'the_password'
        }
    })
    .then(function (response) {
        res.send(JSON.stringify(response.data));
    })
    .catch(function (error) {
        console.log(error);
    });
});

var server = app.listen(port);

Be sure in your project directory you do:

npm init
npm install express
npm install axios
node axios_example.js

You can then test the Node.js REST API using your browser at: http://localhost:5000/search?queryStr=xxxxxxxxx

Similarly you can do post, such as:

axios({
  method: 'post',
  url: 'https://your.service.org/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});

SuperAgent

Similarly you can use SuperAgent.

superagent.get('https://your.service.org?query=xxxx')
.end((err, response) => {
    if (err) { return console.log(err); }
    res.send(JSON.stringify(response.body));
});

And if you want to do basic authentication:

superagent.get('https://your.service.org?query=xxxx')
.auth('the_username', 'the_password')
.end((err, response) => {
    if (err) { return console.log(err); }
    res.send(JSON.stringify(response.body));
});

Ref:

Yuci
  • 27,235
  • 10
  • 114
  • 113
11

I have been using restler for making webservices call, works like charm and is pretty neat.

swapnil_mishra
  • 501
  • 5
  • 7
5

Warning: As of Feb 11th 2020, request is fully deprecated.

One another example - you need to install request module for that

var request = require('request');
function get_trustyou(trust_you_id, callback) {
    var options = {
        uri : 'https://api.trustyou.com/hotels/'+trust_you_id+'/seal.json',
        method : 'GET'
    }; 
    var res = '';
    request(options, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            res = body;
        }
        else {
            res = 'Not Found';
        }
        callback(res);
    });
}

get_trustyou("674fa44c-1fbd-4275-aa72-a20f262372cd", function(resp){
    console.log(resp);
});
Draško Kokić
  • 1,280
  • 1
  • 19
  • 34
Hardik Ranpariya
  • 1,026
  • 2
  • 11
  • 27
5

To use latest Async/Await features

https://www.npmjs.com/package/request-promise-native

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

//code

async function getData (){
    try{
          var rp = require ('request-promise-native');
          var options = {
          uri:'https://reqres.in/api/users/2',
          json:true
        };

        var response = await rp(options);
        return response;
    }catch(error){
        throw error;
    }        
}

try{
    console.log(getData());
}catch(error){
    console.log(error);
}
codemirror
  • 3,164
  • 29
  • 42
4
const http = require('http');
const url = process.argv[2];

http.get(url, function(response) {
  let finalData = "";

  response.on("data", function (data) {
    finalData += data.toString();
  });

  response.on("end", function() {
    console.log(finalData.length);
    console.log(finalData.toString());
  });

});
Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
Seb
  • 500
  • 5
  • 13
3

I didn't find any with cURL so I wrote a wrapper around node-libcurl and can be found at https://www.npmjs.com/package/vps-rest-client.

To make a POST is like so:

var host = 'https://api.budgetvm.com/v2/dns/record';
var key = 'some___key';
var domain_id = 'some___id';

var rest = require('vps-rest-client');
var client = rest.createClient(key, {
  verbose: false
});

var post = {
  domain: domain_id,
  record: 'test.example.net',
  type: 'A',
  content: '111.111.111.111'
};

client.post(host, post).then(function(resp) {
  console.info(resp);

  if (resp.success === true) {
    // some action
  }
  client.close();
}).catch((err) => console.info(err));
Jonatas Walker
  • 13,583
  • 5
  • 53
  • 82
2

If you have Node.js 4.4+, take a look at reqclient, it allows you to make calls and log the requests in cURL style, so you can easily check and reproduce the calls outside the application.

Returns Promise objects instead of pass simple callbacks, so you can handle the result in a more "fashion" way, chain the result easily, and handle errors in a standard way. Also removes a lot of boilerplate configurations on each request: base URL, time out, content type format, default headers, parameters and query binding in the URL, and basic cache features.

This is an example of how to initialize it, make a call and log the operation with curl style:

var RequestClient = require("reqclient").RequestClient;
var client = new RequestClient({
    baseUrl:"http://baseurl.com/api/", debugRequest:true, debugResponse:true});
client.post("client/orders", {"client": 1234, "ref_id": "A987"},{"x-token": "AFF01XX"});

This will log in the console...

[Requesting client/orders]-> -X POST http://baseurl.com/api/client/orders -d '{"client": 1234, "ref_id": "A987"}' -H '{"x-token": "AFF01XX"}' -H Content-Type:application/json

And when the response is returned ...

[Response   client/orders]<- Status 200 - {"orderId": 1320934}

This is an example of how to handle the response with the promise object:

client.get("reports/clients")
  .then(function(response) {
    // Do something with the result
  }).catch(console.error);  // In case of error ...

Of course, it can be installed with: npm install reqclient.

Mariano Ruiz
  • 4,314
  • 2
  • 38
  • 34
1

You can use curlrequest to easily set what time of request you want to do... you can even set headers in the options to "fake" a browser call.

1

Warning: As of Feb 11th 2020, request is fully deprecated.

If you implement with form-data, for more info (https://tanaikech.github.io/2017/07/27/multipart-post-request-using-node.js):

var fs = require('fs');
var request = require('request');
request.post({
  url: 'https://slack.com/api/files.upload',
  formData: {
    file: fs.createReadStream('sample.zip'),
    token: '### access token ###',
    filetype: 'zip',
    filename: 'samplefilename',
    channels: 'sample',
    title: 'sampletitle',
  },
}, function (error, response, body) {
  console.log(body);
});
Syntle
  • 5,168
  • 3
  • 13
  • 34
Lwf804
  • 21
  • 1
0

I found superagent to be really useful, it is very simple for example

const superagent=require('superagent')
superagent
.get('google.com')
.set('Authorization','Authorization object')
.set('Accept','application/json')
David Innocent
  • 606
  • 5
  • 16
0

Update from 2022:

from node.js version v18 on you can use the globally available fetch API (see https://nodejs.org/en/blog/announcements/v18-release-announce/)

There is also an example usage included on their announcement page:

const res = await fetch('https://nodejs.org/api/documentation.json');
if (res.ok) {
  const data = await res.json();
  console.log(data);
}
Fabian Strathaus
  • 3,192
  • 1
  • 4
  • 26