7

Is there a better/more beautiful way to call multiple APIs after another (in serial) as in my example?

  var request = require('request');

  request('http://www.test.com/api1', function (error, response, body) {
    if (!error && response.statusCode == 200) {

      request('http://www.test.com/api1', function (error, response, body) {
        if (!error && response.statusCode == 200) {

          request('http://www.test.com/api1', function (error, response, body) {
            if (!error && response.statusCode == 200) {

              //And so on...

            }
          })

        }
      })

    }
  })
Til
  • 95
  • 1
  • 1
  • 8

5 Answers5

5

Depending on which version of node you are using, promises should be native...

https://nodejs.org/en/blog/release/v4.0.0/

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

var request = require('request');

getRequest('http://www.test.com/api1').then(function (body1) {
    // do something with body1
    return getRequest('http://www.test.com/api2');
}).then(function (body2) {
    // do something with body2
    return getRequest('http://www.test.com/api3');
}).then(function (body3) {
    // do something with body3
    //And so on...
});

function getRequest(url) {
    return new Promise(function (success, failure) {
        request(url, function (error, response, body) {
            if (!error && response.statusCode == 200) {
                success(body);
            } else {
                failure(error);
            }
        });
    });
}
  • thanks for the good example! I have managed to implement this with my other api. But i have problems in handing over my function to my promise generator function. Maybe you can have a look? http://stackoverflow.com/questions/42349936/nodejs-functional-programming-no-access-to-prototype-in-handover-function – Til Feb 20 '17 at 17:27
2

Use async.series If you want to do same operation on a set of URLs, use async.map

Promise can also be used as others suggested.

If you are new with asynchronous programming, I suggest to start with async module then move to Promise (or coroutines, async/await) once you have clearer understanding.

Example:

var request = require('request');

async.series([
  function(callback) {
    request('http://www.test.com/api1', function(error, response, body) {
      if (!error && response.statusCode == 200) {
        return callback(null, response);
      }
      return callback(error || new Error('Response non-200'));
    }
  },
  function(callback) {
    request('http://www.test.com/api2', function(error, response, body) {
      if (!error && response.statusCode == 200) {
        return callback(null, response);
      }
      return callback(error || new Error('Response non-200'));
    }
  }
],
// optional callback
function(err, results) {
  if (err) {
    // Handle or return error
  }
  // results is now array of responses
});
Sangharsh
  • 2,999
  • 2
  • 15
  • 27
  • This works great! Use async.parallel instead of async.series for parallel calls which is also working fine – Praveen Sep 27 '18 at 06:20
1

You can use request-promise instead of request and then you would be able to chain all the promises!

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

var rp = require('request-promise');

rp(options)
.then(function (body) {
   return rp(...)
}).then(()){
   ...
}

In my honest opinion and if the order is not important you should do all the requests in parallel!

Marco Talento
  • 2,335
  • 2
  • 19
  • 31
0

Use Promises.

https://www.promisejs.org
https://www.promisejs.org/patterns/

It is much better than callbacks and it can execute one request after another in serial.

0

You may want to consider using JavaScript Promises. They sure provide a more beautiful way to handle callbacks.

Ethan
  • 69
  • 1
  • 1