我是Node.JS的新手,并开始寻找最佳实践文章等,以确保我的node.js代码是单元测试友好的,并遵循node.js最佳实践。在研究时我遇到了以下代码示例:
app.js:
module.exports = function (flights) {
var express = require('express');
var routes = require('./routes')(flights);
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(function (req, res, next) {
res.set('X-Powered-By', 'Flight Tracker');
next();
});
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/flight/:number', routes.flight);
app.put('/flight/:number/arrived', routes.arrived);
app.get('/list', routes.list);
return app;
}
server.js:
var http = require('http'),
flights = require('./data'),
app = require('./app')(flights);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
模块(index.js):
var Flight = function () {
this.data = {
number: null,
origin: null,
destination: null,
departs: null,
arrives: null,
actualDepart: null,
actualArrive: null
};
this.fill = function (info) {
for(var prop in this.data) {
if(this.data[prop] !== 'undefined') {
this.data[prop] = info[prop];
}
}
};
this.triggerDepart = function () {
this.data.actualDepart = Date.now();
};
this.triggerArrive = function () {
this.data.actualArrive = Date.now();
};
this.getInformation = function () {
return this.data;
};
};
module.exports = function (info) {
var instance = new Flight();
instance.fill(info);
return instance;
};
路由(index.js):
module.exports = function (flights) {
var flight = require('../flight');
for(var number in flights) {
flights[number] = flight(flights[number]);
}
var functions = {};
functions.flight = function(req, res){
var number = req.param('number');
if (typeof flights[number] === 'undefined') {
res.status(404).json({status: 'error'});
} else {
res.json(flights[number].getInformation());
}
};
functions.arrived = function (req, res) {
var number = req.param('number');
if (typeof flights[number] === 'undefined') {
res.status(404).json({status: 'error'});
} else {
flights[number].triggerArrive();
res.json({status: 'done'});
}
};
functions.list = function (req, res) {
res.render('list', {
title: 'All Flights',
flights: flights});
};
return functions;
};
虽然我喜欢这种方式很有组织,但我没有看到在这种情况下处理多个模块的有效方法。假设我有用户,Initerary等的附加模块。当我开始向app.js文件添加路由时,这似乎很快就会变得混乱,更不用说需要将多少潜在参数传递到app.js 。如果我有一个需要20个或更多模块的大型休息层怎么办?我正在寻找任何doc或链接或示例,展示我应该在node.js中执行此操作的简洁方法。
答案 0 :(得分:0)
使用express.Router()
的子路由器进行粒化和封装。然后,每个路由器都会成为它自己的模块,这样您就不必在app.js
中明确添加每一条路由。
<强> user.js的强>
"use strict";
// Create a router
var express = require("express"),
router = express.Router();
router.get("/", function (req, res, next) {
// All your User logic
res.send([
{
name: "Bob"
},
{
name: "John"
}
]);
});
router.get("/:number", function (req, res, next) {
res.send({
name: "Bob"
});
});
router.post("/", function (req, res, next) {
res.send({
name: "New Guy"
});
});
module.exports = router;
<强> App.js 强>
var app = express();
app.use("/user", require("./User"));
现在您可以GET
/user
,GET
/user/SOME_ID
和POST
到/user
。如果你想将子路径移动到其他地方也很简单,因为为用户路由定义的方法是相对的。
答案 1 :(得分:0)
我也有一个名为campaign_service的大型企业应用程序,由许多模块组成。
这就是我在文件campaign_router.js中组织路线的方法。
var express = require('express');
var router = express.Router();
var cm = require('./campaign_manager.js');
var qsc = require('./converters/qs_converter.js');
var jsc = require('./converters/json_converter.js');
var xmlc = require('./converters/xml_converter.js');
var fc = require('./converters/f_converter');
var fc2 = require('./converters/fjt2_converter');
var cv = require('./campaign_validator.js');
var templates = require('./template_list.js');
var AuthDecoder = require('authdecoder');
var adc = AuthDecoder.middleware;
router.get ('/campaigns/qs', qsc, adc, cv, cm.createCampaign); // Creates a new campaign using query string params
router.post ('/campaigns/b/xml', xmlc, adc, cv, cm.createCampaign); // Creates a new campaign using xml payload
router.post ('/campaigns/file', fc, adc, cv, cm.createCampaign); // Creates a new campaign using uploaded file
router.post ('/campaigns/file/type2', fc2, adc, cv, cm.createCampaign); // Creates a new campaign using uploaded file
router.post ('/campaigns/js', jsc, adc,cv, cm.createCampaign); // Creates a new bulk campaign using json payload
router.get ('/campaigns/', adc, cm.getCampaigns); // Returns a list of bulk campaigns accessible for the invoking user.
router.get ('/campaigns/date', adc, cm.getCampaignsByRange); // Returns a list of bulk campaigns accessible for the invoking user.
router.get ('/campaigns/b/:id', adc, cm.getCampaign); // returns the details of a specific campoaign
router.put ('/campaigns/b/id', cm.updateCampaign); // Updates a specified campaign
router.delete ('/campaigns/b/:id', cm.deleteCampaign); // deletes a campaign
router.post ('/pause', adc, cm.pauseJob); // Pauses an ongoing campaign
router.post ('/resume', adc, cm.resumeJob); // Resumes a paused campaign
router.post ('/cancel', adc,cm.cancelJob); // Resumes a paused campaign
//router.post ('/reschedule', adc,cm.rescheduleCampaign); // Resumes a paused campaign
//router.get ('/', cm.pingCampaignServer);
router.get ('/templates', adc, templates.listTemplates); // gives the campaign server templates
突出点:
基本上,我很容易将代码扩展到多个模块并通过路由器文件导入它们。
修改强> 添加了使用场景 Index.js
var routes = require('./campaign_router.js');
...
app.use('/campaignservice', routes);