Expressjs: how to distribute route middleware along routes

I have defined several intermediate routing programs and want to share them across several 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 automatically downloads all routes to a directory. A possible route file might look like this:

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

Now I got the routing 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 as:

 var User = require('../models/user'); module.exports = function(app) { app.get('/contacts', isAuthenticated, loadUser, function(req, res, next) { res.json(req.user.contacts); }); }; 

I would also like to avoid having to use them in 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 ...

+4
source share
1 answer

Personally, I would declare a joint middleware in the application, and 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 create a stack (an array, not an object):

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

And if these intermediaries are used on all but a few routes, 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) use this middleware, or if it should happen in a specific order relative to other middleware, you can use app.all('*', theseMiddlewares)

+13
source

All Articles