在這一節(jié)我們將實現(xiàn)一個Express路由,以獲取角色信息并存儲進數(shù)據(jù)庫。我們將使用EVE Online API來獲取給定character name的Character ID,Race以及Bloodline。
注意:角色性別并不是公開數(shù)據(jù),它需要一個API key。在我看來,讓New Eden
Faces變得非常棒的是它的開放生態(tài):用戶并不需要登錄即可添加、查看EVE中的角色。這也是為什么我在表單里添加了性別選項讓用戶自己填寫的緣故,雖
然它的準確性的確依賴于用戶的誠信。
下面的表格列出了每個路由的職責。不過,我們不會實現(xiàn)所有的路由,如果需要的話你可以自己實現(xiàn)它們。
Route | POST | GET | PUT | DELETE |
---|---|---|---|---|
/api/characters | 添加新角色 | 獲取隨機兩個角色 | 更新角色投票勝負信息 | 刪除所有角色 |
/api/characters/:id | N/A | 獲取角色 | 更新角色 | 刪除角色 |
在server.js文件前面添加下列依賴:
var async = require('async');var request = require('request');
我們將使用async.waterfall
來管理多異步操作,使用request來向EVE Online API發(fā)起HTTP請求。
將我們的第一個路由添加到Express中間件后面,在第8步創(chuàng)建的React中間件前面:
/**
* POST /api/characters
* Adds new character to the database.
*/
app.post('/api/characters', function(req, res, next) {
var gender = req.body.gender;
var characterName = req.body.name;
var characterIdLookupUrl = 'https://api.eveonline.com/eve/CharacterID.xml.aspx?names=' + characterName;
var parser = new xml2js.Parser();
async.waterfall([
function(callback) {
request.get(characterIdLookupUrl, function(err, request, xml) {
if (err) return next(err);
parser.parseString(xml, function(err, parsedXml) {
if (err) return next(err);
try {
var characterId = parsedXml.eveapi.result[0].rowset[0].row[0].$.characterID;
Character.findOne({ characterId: characterId }, function(err, character) {
if (err) return next(err);
if (character) {
return res.status(409).send({ message: character.name + ' is already in the database.' });
}
callback(err, characterId);
});
} catch (e) {
return res.status(400).send({ message: 'XML Parse Error' });
}
});
});
},
function(characterId) {
var characterInfoUrl = 'https://api.eveonline.com/eve/CharacterInfo.xml.aspx?characterID=' + characterId;
request.get({ url: characterInfoUrl }, function(err, request, xml) {
if (err) return next(err);
parser.parseString(xml, function(err, parsedXml) {
if (err) return res.send(err);
try {
var name = parsedXml.eveapi.result[0].characterName[0];
var race = parsedXml.eveapi.result[0].race[0];
var bloodline = parsedXml.eveapi.result[0].bloodline[0];
var character = new Character({
characterId: characterId,
name: name,
race: race,
bloodline: bloodline,
gender: gender,
random: [Math.random(), 0]
});
character.save(function(err) {
if (err) return next(err);
res.send({ message: characterName + ' has been added successfully!' });
});
} catch (e) {
res.status(404).send({ message: characterName + ' is not a registered citizen of New Eden.' });
}
});
});
}
]);
});
注意:我一般在路由上面寫塊級注釋,包括完整路徑和簡介,這樣我就能使用查找功能(Command+F)來快速尋找路由,如下圖所示:
下面就來按部就班的看一下它是如何工作的:
async.waterfall
中的下一個函數(shù)。在瀏覽器打開http://localhost:3000/add 并添加一些角色,你可以使用下面的名字:
或者,你也可以下載這個MongoDB文件dump并將它導入到你的數(shù)據(jù)庫,它包含4000以上個角色。如果你之前添加了其中的一些角色,可能會出現(xiàn)“duplicate key errors”錯誤,不用管它:
下載之后使用下面的命令將它導入到數(shù)據(jù)庫:
$ mongorestore newedenfaces.bson
鑒于我們還沒有實現(xiàn)相關的API,現(xiàn)在你還不能看到總的角色數(shù),我們將在下下節(jié)來實現(xiàn)。
下面讓我們先創(chuàng)建Home組件,這是一個初始頁面,上面會并排顯示兩個角色。
(譯者注:下面會先第15節(jié)再第14節(jié),原文如此)
更多建議: