NodeJS 请求多个 api 端点
NodeJS request multiple api endpoints
好的,所以我正在尝试使用请求模块向 API 端点发出两个或更多请求。我正在渲染一个 HTML 文件并使用以下代码将返回的 JSON 传递给车把模板:
res.render('list.html', {
title: 'List',
data: returnedJSON
}
然后我可以很容易地在我的车把模板中迭代这个 JSON。
我遇到的问题是,我现在需要使用多个数据源,其中将根据类别 JSON 响应构建类别列表,并根据员工 JSON 响应构建员工列表.我想要一个可以执行此操作的简单解决方案,但可以扩展它以使用任意数量的数据源。
下面是我拥有的一个数据源的完整代码片段:
request({
url: 'https://api.com/categories',
headers: {
'Bearer': 'sampleapitoken'
}
}, function(error, response, body) {
if(error || response.statusCode !== 200) {
// handle error
} else {
var json = JSON.parse(body);
res.render('list.html', {
title: 'Listing',
data: json
});
}
});
这对一个端点非常有效,但如前所述,我现在需要使用多个请求并具有多个数据源,例如:
request({
url: ['https://api.com/categories','https://api.com/staff'],
headers: {
'Bearer': 'sampleapitoken'
}
}, function(error, response, body1, body2) {
if(error || response.statusCode !== 200) {
// handle error
} else {
var json1 = JSON.parse(body1);
var json2 = JSON.parse(body2);
res.render('list.html', {
title: 'Listing',
staff: json1,
categories: json2
});
}
});
我很欣赏以上内容并非如此,但我希望这可以帮助传达我正在努力实现的目标。
提前致谢:)
您可以使用 async 库映射您的请求对象并将它们传递给实际请求,并且 return 所有结果都在一个回调中。
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]
}
}
});
然而,更简单的方法是利用承诺,这可以通过 bluebird 和承诺请求库来完成,或者使用已经承诺的请求库 request-promise。您仍然需要包含一个 promise/A+ 库来异步映射结果。
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
});
请务必注意,所有最新版本的节点和浏览器都支持开箱即用的 Promises,无需外部库即可实现。
看来 promises 会有帮助。
最简单的可能是创建一个新的请求方法,returns 一个承诺(或用 Bluebird 等承诺),然后等待所有承诺完成,并处理数据
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);
});
好的,所以我正在尝试使用请求模块向 API 端点发出两个或更多请求。我正在渲染一个 HTML 文件并使用以下代码将返回的 JSON 传递给车把模板:
res.render('list.html', {
title: 'List',
data: returnedJSON
}
然后我可以很容易地在我的车把模板中迭代这个 JSON。
我遇到的问题是,我现在需要使用多个数据源,其中将根据类别 JSON 响应构建类别列表,并根据员工 JSON 响应构建员工列表.我想要一个可以执行此操作的简单解决方案,但可以扩展它以使用任意数量的数据源。
下面是我拥有的一个数据源的完整代码片段:
request({
url: 'https://api.com/categories',
headers: {
'Bearer': 'sampleapitoken'
}
}, function(error, response, body) {
if(error || response.statusCode !== 200) {
// handle error
} else {
var json = JSON.parse(body);
res.render('list.html', {
title: 'Listing',
data: json
});
}
});
这对一个端点非常有效,但如前所述,我现在需要使用多个请求并具有多个数据源,例如:
request({
url: ['https://api.com/categories','https://api.com/staff'],
headers: {
'Bearer': 'sampleapitoken'
}
}, function(error, response, body1, body2) {
if(error || response.statusCode !== 200) {
// handle error
} else {
var json1 = JSON.parse(body1);
var json2 = JSON.parse(body2);
res.render('list.html', {
title: 'Listing',
staff: json1,
categories: json2
});
}
});
我很欣赏以上内容并非如此,但我希望这可以帮助传达我正在努力实现的目标。
提前致谢:)
您可以使用 async 库映射您的请求对象并将它们传递给实际请求,并且 return 所有结果都在一个回调中。
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]
}
}
});
然而,更简单的方法是利用承诺,这可以通过 bluebird 和承诺请求库来完成,或者使用已经承诺的请求库 request-promise。您仍然需要包含一个 promise/A+ 库来异步映射结果。
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
});
请务必注意,所有最新版本的节点和浏览器都支持开箱即用的 Promises,无需外部库即可实现。
看来 promises 会有帮助。
最简单的可能是创建一个新的请求方法,returns 一个承诺(或用 Bluebird 等承诺),然后等待所有承诺完成,并处理数据
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);
});