2012-07-27 51 views
4

我已经定义了多个路由中间件,并希望跨多个路由/控制器共享它们。Expressjs:如何在路径上共享路由中间件

这里是我的设置:

app.js需要./routes/index.js:

// load fs module 
var fs = require('fs'); 

// import routing files 
module.exports = function(app){ 
    fs.readdirSync(__dirname).forEach(function(file) { 
     if (file == "index.js") return; 
     var name = file.substr(0, file.indexOf('.')); 
     require('./' + name)(app); 
    }); 
}; 

index.js全自动负载在目录中的所有路线。一个可能的路径文件可以看起来像:

module.exports = function(app) { 

    app.get('/contacts', function(req, res, next) { 
     // routing stuff 
    }); 

}; 

现在,我得到的路线中间件:

function isAuthenticated(req, res, next) { 
    if (!req.session.authenticated) return next(new Error('user not authenticated')); 
}; 

function loadUser(req, res, next) { 
    var query = User.findById(req.session.user_id); 
    query.populate('contacts'); 
    query.exec(function(err, user) { 
     if (err) return next(err); 
     req.user = user; 
     next(); 
    }); 
} 

,我想用这样的:

var User = require('../models/user'); 

module.exports = function(app) { 

    app.get('/contacts', isAuthenticated, loadUser, function(req, res, next) { 
     res.json(req.user.contacts); 
    }); 

}; 

我也想避免要求他们横跨所有路由文件。

一个可能的解决方案也将是:

// load fs module 
var fs = require('fs'); 

var routeMiddleware = { 
    loadUser: function(req, res, next) { // logic }, 
    isAuthenticated: function(req, res, next) { // logic }, 
}; 


// import routing files 
module.exports = function(app){ 
    fs.readdirSync(__dirname).forEach(function(file) { 
     if (file == "index.js") return; 
     var name = file.substr(0, file.indexOf('.')); 
     require('./' + name)(app, routeMiddleware); 
    }); 
}; 

,但我认为不是最好的...

回答

13

我个人申报共享中间件在应用程序中,而不是在控制器,即:

路由/ home.js:

module.exports = function(req, res, next) { \\ Code } 

app.js:

app.get('/', thisMiddleware, thatMiddleware, require('./routes/home')) 

你也可以做一个堆栈(数组,而不是一个对象):

theseMiddlewares = [thisMiddleware, thatMiddleware] 
app.get('/', theseMiddlewares, require('./routes/home')) 

如果这些中间件对所有线路使用除少数,你可以做到以下几点:

theseMiddlewares = function(req, res, next) { 
    if (req.url.match(some_regex_for_urls_to_skip)) next() 
    else { 
    \\ do stuff... 
    next() 
    } 
} 

现在你可以app.use(theseMiddlewares)中间件,或者如果它需要相对于其他中间件一定的顺序发生,你可以使用app.all('*', theseMiddlewares)

+1

你好,interessting解决方案。还有一种方法可以在应用程序中保存中间件本身吗?我想用他们manuelly没有要求他们的压力。 – bodokaiser 2012-07-28 07:23:47

+0

就像我说过的那样,我会在应用中声明路由和中间件,并使路由中的每个模块都成为中间件,而不是像你这样的路由。这样你只需要在你的应用中使用中间件,而不是每个路由模块。 – 2012-07-28 09:16:47