NodeJS / Express MVC模式中的REST数据源
在Express MVC应用程序中包含外部REST数据源的最佳做法是什么? 我们是否应该为从外部REST源检索的实体创build一个模型?
我们来看一下这个实际的例子:
我们的出发点是使用mongoose作为ODM的user.js模型。
var mongoose = require('mongoose'); var userModel = function () { //Define a simple schema for our user. var userSchema = mongoose.Schema({ name: String, twitterId: Number }); return mongoose.model('User', userSchema); }; module.exports = new userModel();
我们的目标是显示特定用户的所有推文,所以我们创build一个控制器controller / userTweets.js,在那里为View准备数据。
我们应该如何在应用程序中包含Twitter REST API来处理这个用例呢? (比方说,我们正在使用一个nodejs客户端的twitter apis)
我更愿意为推特实体使用特定的模型,然后使用我们的模型从控制器中检索用户的推特,但我们的tweet.js模型应该如何呢? 还是应该以不同的方式devise我们的REST API集成?
我会创build一个名为Tweet
的类,并为其创build相应的存储库。
假设你正在使用es6,因为为什么不呢。
让我们把它tweets.js
'use strict'; module.exports = function (cfg) { class Tweet { constructor() { this.userid = null; this.text = null; } } class Repo { static getTweetsForUser(usedId) { // make a call to twitter api, use https://www.npmjs.com/package/request // psuedo code let _ = require('lodash'); getTweets(userid, function (err, tweets) { return new Promise(function (resolve, reject) { if (err) { return reject(err); } let data = [], tweet = new Tweet; if (! tweets.length) { return resolve(data); } resolve(_.collect(tweets, function (t) { tweet.userId = userId; tweet.text = t.getTheTweet; return tweet; })); }); }); } } return { 'tweet': Tweet, 'repo' : Repo } }
//导出类似上面的任何模块,可以称之为index.js
strict'; 让_ = require('lodash');
let modules = [ 'tweets', ]; // cfg = any app configs that you might need in modules function init(cfg) { let core = {}; return _.collect(modules, function (m) { core[m] = require('./' + m)(cfg); }); } module.exports = init;
示例 – https://github.com/swarajgiri/express-bootstrap/blob/master/core/index.js
现在在路由方面,在你的主要服务器server.js
,将模块注入到一个express()
的实例中,
app.set('core', require('path/to/core/index')(whateverConfigYouMightNeed))
一旦完成,你的路线可以看起来像
'use strict' let wrap = require('co-wrap'); route.get(':userId/tweets'), wrap(function* (req, res, next) { let tweets = []; try { tweets = yield req.app.get('core').tweets.Repo.getTweetsForUser(req.params.userId) } catch(e) { // let the common error handler do its job. return next(e); } // render whatever view you want. });