如何使用NodeJS和Express从app.js中分离路线和模型

我正在使用Node和Express创build一个应用程序。 但是,我可以看到很快就会很难pipe理放在app.js所有路由。 我已将所有模型放置在子目录/models

这是我的应用程序目前的结构:

 app.js models -- products -- customers -- ... public views node_modules 

app.js

 var express = require('express'), routes = require('./routes'), user = require('./routes/user'), http = require('http'), path = require('path'), EmployeeProvider = require('./models/employeeprovider').EmployeeProvider, Products = require('./models/products').Products, Orders = require('./models/orders').Orders, Customers = require('./models/customers').Customers, checkAuth = function(req, res, next) { if (!req.session.user_id) { res.send('You are not authorized to view this page'); } else { next(); } }; var app = express(); 

然后是一些configuration,如portviews目录,渲染引擎等

进一步下来app.js我有路线:

 app.get('/product/edit', auth, function(req, res) { Products.findAll(function(error, prds) { res.render('product_edit', { title: 'New Product', products: prds }); }); }); 

在顶部,我将models/products.js的内容分配给一个variables,所有工作都很好。 但是保持app.js所有路线并不理想。 但是,如果我将路线移动到routes/product.js并加载Products模型:

 var prod = require('../models/products.js'); 

我得到一个错误,说对象没有方法findAll

我究竟做错了什么? 我怎样才能从app.js删除路线?

       

网上收集的解决方案 "如何使用NodeJS和Express从app.js中分离路线和模型"

从4.x版本开始, Router被添加来支持你的情况。

路由器对象是中间件和路由的独立实例。 你可以把它看作是一个只能执行中间件和路由function的“小应用程序”。 每个Express应用程序都有一个内置的应用程序路由器。

来自expressjs站点的示例:

 // routes/calendarRouter.js var express = require('express'); var router = express.Router(); // invoked for any requested passed to this router router.use(function(req, res, next) { // .. some logic here .. like any other middleware next(); }); // will handle any request that ends in /events // depends on where the router is "use()'d" router.get('/events', function(req, res, next) { // .. }); module.exports = router; 

然后在app.js中:

 // skipping part that sets up app var calendarRouter = require('./routes/calendarRouter'); // only requests to /calendar/* will be sent to our "router" app.use('/calendar', calendarRouter); // rest of logic 

由于我不喜欢重复,所以我这样做:

 // app.js //... var routes = requireDir('./routes'); // https://www.npmjs.org/package/require-dir for (var i in routes) app.use('/', routes[i]); //... 

每个路由文件都是这样的:

 // routes/someroute.js var express = require('express'); var router = express.Router(); router.get('/someroute', function(req, res) { res.render('someview', {}); }); module.exports = router; 

这样你可以避免像这样的重复列表:

 app.use('/' , require('./routes/index')); app.use('/repetition' , require('./routes/repetition')); app.use('/is' , require('./routes/is')); app.use('/so' , require('./routes/so')); app.use('/damn' , require('./routes/damn')); app.use('/boring' , require('./routes/boring')); 

编辑:这些长的例子假设每个路线文件包含如下内容:

 var router = express.Router(); router.get('/', function(req, res, next) { // ... next(); }); module.exports = router; 

所有这些都可以挂载到“根”,但他们是什么“根”,实际上是一个特定的path给app.use ,因为你可以挂载path到特定的path(这也支持像指定path正则expression式,快递是相当整齐的问候,你可以做什么与路由)。

我可以build议你这个文件结构(根据模块化的Web应用程序与Node.js和从tjholowaychukexpression ):

 app.js modules users index.js model.js users-api index.js static-pages index.js 

user-apistatic-pages导出expressjs应用程序,您可以轻松地将它们安装在app.js. 在users模块中,您可以描述一些数据访问操作以及与用户实体操作有关的所有方法(如创build,更新等)。 我们的API模块将使用所有这些方法。

这里是app.js文件的示例代码(没有常见的快递材料,只安装来自不同模块的路线):

 var express = require('express'); var app = express(); // mount all the applications app.use('/api/v1', require("user-api")); app.use(require("static-pages")); app.listen(3000); 

以这种方式使用你的模块,你必须像这样启动你的应用NODE_PATH=modules node app.js (我把这一行放在脚本部分的package.json文件中)。

这里是users模块的示例代码:

index.js

 User = require("./model"); module.exports = { get: function(id, callback) { User.findOne(id, function(err, user) { callback(err, user); }); }, create: function(data, callback) { // do whatever with incoming data here data = modifyDataInSomeWay(data); var newUser = new User(data); newUser.save(function(err, savedUser) { // some logic here callback(err, savedUser); }); } }; 

model.js (当然是用Mongoose的东西!)

 var mongoose = require('mongoose'); var Schema = mongoose.Schema; var User = new Schema({ firstname : {type: String, required: false}, lastname : {type: String, required: false}, email : {type: String, required: true} }); module.exports = mongoose.model('user', User); 

user-api模块的例子(这里是关于分离路线和模型的答案的主要部分)。

 var users = require("users"); var express = require("express"); var app = module.exports = express(); // we export new express app here! app.post('/users', function(req, res, next) { // try to use high-level calls here // if you want something complex just create another special module for this users.create(req.body, function(err, user) { if(err) return next(err); // do something on error res.json(user); // return user json if ok }); }); 

static-pages例子。 如果你不打算build立一种REST接口,你可以简单地创build几个模块,只会渲染页面。

 var express = require("express"); var app = module.exports = express(); // we export new express app here again! app.get('/', function(req, res, next) { res.render('index', {user: req.user}); }); app.get('/about', function(req, res, next) { // get data somewhere and put it in the template res.render('about', {data: data}); }); 

当然你可以用模块做你想做的事情。 expressjs的主要思想是使用许多小应用程序,而不是单个应用程序。

关于nodejs模块,你可以阅读stackoverflow和文档 。

希望这可以帮助。