我正在开发一个应用程序NodeJS
和Express
。此应用程序的目标是提供从多个不同的API端点获取的数据,全部在一个页面中提供。Express - 来自不同端点的多个异步请求
不幸的是,我与NodeJS
和Express
相对较新,但已经做了一些研究,我知道,你可以用 async
模块多asyncronous请求。但是,我不太清楚如何解决这个问题,需要您的帮助才能让我回到赛道上。
我需要提供两个异步请求来获取所有预期的数据,并最终将它们作为一个JSON链接在一起。该requets如下:
请求1 - 今晚的比赛
首先,我需要今晚(http://exampleapi.com/api/v1/schedule)
输出JSON
数据的预定游戏从这个API端点如下:
{
"date": "2016-12-15",
"totalGames": 3,
"games": [
{
"id": 1,
"link": "/api/v1/game/1"
},
{
"id": 2,
"link": "/api/v1/game/2"
},
{
"id": 3,
"link": "/api/v1/game/3"
}
]
}
在下面,从我的文件中有一条路径以上面解释的方式输出提取的JSON
。
附注/问题:虽然for
循环迭代3次以上,但第一个对象将被输出三次而不是三个不同的对象。
server.js
router.get('/test/schedule_test', function(req, res) {
res.contentType('application/json'); // content type of the response object
var url = 'http://exampleapi.com/api/v1/schedule'; // url of the api endpoint
// make an request to the endpoint
request(url, function (error, response, body) {
// If the request was successfully made
if (!error && response.statusCode == 200) {
var body = JSON.parse(body);
var schedule, totalGames, date, games = [], id, link, game;
// Schedule object
schedule = {
"totalGames": totalGames,
"date": date,
"games": games
};
schedule.totalGames = body.totalGames;
schedule.date = body.dates[0].date;
game = {"id": id, "link": link};
for(var i = 0; i < schedule.totalGames; i++) {
// Here's the part where I think I've made some mistakes and why it outputs a single object over so many times the value of "totalGames" is.
game.id = body.dates[0].games[i].gamePk;
game.link = body.dates[0].games[i].link;
games.push({
"game": game
});
}
res.status(200).json(schedule);
} else {
res.status(404).json({"error": true});
}
});
});
接下来,我需要为每个被链接的属性值提供的链接的异步请求获取各参赛队的队相关的数据。
请求2 - 团队相关的数据
从这个API端点产出预期JSON
如下:
{
"gameData": {
"teams": {
"away": {
"link": "/api/v1/teams/1",
"name": "Example team 1",
"abbreviation": "EXT1"
},
"home": {
"link": "/api/v1/teams/2",
"name": "Example team 2",
"abbreviation": "EXT2"
}
},
"venue": {
"name": "Georgestown Palace, Manitoba"
}
}
}
下面,有从我的文件,做输出路线所取得的JSON
以上面解释的方式。
server.js
router.get('/test/team_test', function(req, res) {
// Note that these urls should be generated dynamically from the previous request
var urls = [
'http://exampleapi.com/api/v1/teams/1',
'http://exampleapi.com/api/v1/teams/2'
];
async.map(urls, function(url, callback) {
// iterator function
request(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
// do any further processing of the data here
var body = JSON.parse(body);
var teams;
// Away team
var away_link, away_name, away_abbr;
var away = {"link": away_link, "name": away_name, "abbreviation": away_abbr};
var away_link = body.gameData.teams.away.link;
away.link = away_link;
var away_name = body.gameData.teams.away.name;
away.name = away_name;
var abbreviation = body.gameData.teams.away.abbreviation;
away.abbrreviation = abbreviation;
// Home team
var home_link, home_name, home_abbr;
var home = {"link": home_link, "name": home_name, "abbreviation": home_abbr};
var home_link = body.gameData.teams.home.link;
home.link = home_link;
var home_name = body.gameData.teams.home.name;
home.name = home_name;
var home_abbreviation = body.gameData.teams.home.abbreviation;
home.abbreviation = home_abbreviation;
var arena = body.gameData.venue.name;
teams = {
"teams": {
"away": away,
"home": home
},
"played_at": arena
};
callback(null, teams);
} else {
callback(error || response.statusCode);
}
});
}, function(err, results) {
// completion function
if (!err) {
res.contentType('application/json');
res.status(200).json(results);
} else {
// handle error here
console.log(err);
}
});
});
预期结果
最后,我需要加入这两个不同的输出到一个JSON
输出。预期结果如下所示:
{
"date": "2016-12-15",
"totalGames": 3,
"games": [
{
// #1 joined object
// data from the first api request
"id": 1,
"link": "/api/v1/game/1",
// data from the second api request
"teams": {
"away": {
"link": "/api/v1/teams/1",
"name": "Example team 1",
"abbreviation": "EXT1"
},
"home": {
"link": "/api/v1/teams/2",
"name": "Example team 2",
"abbreviation": "EXT2"
}
},
"venue": {
"name": "Georgestown Palace, Manitoba"
}
},
{
// #2 joined object
"id": 2,
"link": "/api/v1/game/3",
"teams": {
"away": {
"link": "/api/v1/teams/3",
"name": "Example team 3",
"abbreviation": "EXT3"
},
"home": {
"link": "/api/v1/teams/4",
"name": "Example team 4",
"abbreviation": "EXT4"
}
},
"venue": {
"name": "Portsmouth Valley, New Jersey"
}
},
{
// #3 joined object
"id": 3,
"link": "/api/v1/game/3",
"teams": {
"away": {
"link": "/api/v1/teams/5",
"name": "Example team 5",
"abbreviation": "EXT5"
},
"home": {
"link": "/api/v1/teams/6",
"name": "Example team 6",
"abbreviation": "EXT6"
}
},
"venue": {
"name": "Colorado Springs, Colorado"
}
}
]
}
任何帮助将不胜感激。预先感谢和快乐的编码!
怎么样的事实:一些端点的URL生成动态的基础上先前请求的链接属性值? –
@B_CooperA - 显然你必须做一些更具体的事情。我不得不明白你想要做什么,因为我没有看到你的问题中的代码所示的情况。我仍然使用承诺来协调异步结果,但是对于您的具体情况还没有一个通用的答案。我回答了你我正在做什么,它是从多个独立端点并行获取数据并使用结果生成一个页面。 – jfriend00