NodeJS request multiple api endpoints

北战南征 提交于 2019-12-02 21:28:36

You can use the async library to map your request objects and pass them to an actual request and return all results in one callback.

var async = require("async");
var request = require("request");

// create request objects
var requests = [{
  url: 'https://api.com/categories',
  headers: {
    'Bearer': 'sampleapitoken'
  }
}, {
  url: 'https://api.com/staff',
  headers: {
    'Bearer': 'sampleapitoken'
  }
}];

async.map(requests, function(obj, callback) {
  // iterator function
  request(obj, function(error, response, body) {
    if (!error && response.statusCode == 200) {
      // transform data here or pass it on
      var body = JSON.parse(body);
      callback(null, body);
    } else {
      callback(error || response.statusCode);
    }
  });
}, function(err, results) {
  // all requests have been made
  if (err) {
    // handle your error
  } else {
    console.log(results);
    for (var i = 0; i < results.length; i++) {
      // request body is results[i]
    }
  }
});

However a simpler way would to leverage promises, this can be done with bluebird and promisifying the request lib, or use the already promisified request lib request-promise. You'll still want to include a promise/A+ lib to map the results asynchronously.

var Promise = require("bluebird");
var request = require('request-promise');

// create request objects
var requests = [{
  url: 'https://api.com/categories',
  headers: {
    'Bearer': 'sampleapitoken'
  }
}, {
  url: 'https://api.com/staff',
  headers: {
    'Bearer': 'sampleapitoken'
  }
}];

Promise.map(requests, function(obj) {
  return request(obj).then(function(body) {
    return JSON.parse(body);
  });
}).then(function(results) {
  console.log(results);
  for (var i = 0; i < results.length; i++) {
    // access the result's body via results[i]
  }
}, function(err) {
  // handle all your errors here
});

It's important to note that all latest versions of node and browsers support Promises out of the box and this can be implemented without external libraries.

Seems like promises could help.

The easiest would probably be to create a new request method that returns a promise (or promisifying with Bluebird etc), then wait for all promises to finish, and handle the data

function doReq(url, what) {
    return new Promise(function(resolve, reject) {
        request({
            url: url,
            headers: {
                'Bearer': 'sampleapitoken'
            }
        }, function(error, response) {
            if(error || response.statusCode !== 200) {
                reject(error);
            } else {
                var data = {};
                (Array.isArray(what) ? what : [what]).forEach(function(item, index) {
                    data[item] = JSON.parse(arguments[index + 2]);
                });
                resolve( data );
            }
        });
    });
}

Promise.all([
    doReq('https://api.com/categories', 'data'), 
    doReq(['https://api.com/categories','https://api.com/staff'], ['staff', 'categories'])
]).then(function() {
    var obj = {title : 'Listing'};
    [].slice.call(arguments).forEach(function(arg) {
        Object.keys(arg).forEach(function(key) {
            obj[key] = arg[key];
        });
    });
    res.render('list.html', obj);
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!