Reputation: 15752
I have defined multiple route middleware and want to share them across multiple routes/controllers.
Here is my setup:
app.js requires ./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 loads all routes automaticly in the dir. A possible routes file can look like:
module.exports = function(app) {
app.get('/contacts', function(req, res, next) {
// routing stuff
});
};
Now I got route middleware:
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();
});
}
which I want to use like:
var User = require('../models/user');
module.exports = function(app) {
app.get('/contacts', isAuthenticated, loadUser, function(req, res, next) {
res.json(req.user.contacts);
});
};
I also would like to avoid requiring them accross all routing files.
A possible solution would also be:
// 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);
});
};
but I think not the best...
Upvotes: 5
Views: 6739
Reputation: 20345
Personally I would declare shared middleware in the app, not in the controllers, i.e.:
routes/home.js:
module.exports = function(req, res, next) { \\ Code }
app.js:
app.get('/', thisMiddleware, thatMiddleware, require('./routes/home'))
You can also make a stack (array, not an object):
theseMiddlewares = [thisMiddleware, thatMiddleware]
app.get('/', theseMiddlewares, require('./routes/home'))
And if these middlewares are used on all routes except a few, you can do the following:
theseMiddlewares = function(req, res, next) {
if (req.url.match(some_regex_for_urls_to_skip)) next()
else {
\\ do stuff...
next()
}
}
Now you can app.use(theseMiddlewares)
that middleware, or if it needs to happen in a certain order relative to other middleware, you can use app.all('*', theseMiddlewares)
Upvotes: 13