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...
We can use more than one middleware on an Express app instance, which means that we can use more than one middleware inside app.
Middleware functions are functions that have access to the request object ( req ), the response object ( res ), and the next function in the application's request-response cycle. The next function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware.
Note: Router functions are Express middleware, which means that they must either complete (respond to) the request or call the next function in the chain.
Error-handling middleware always takes four arguments. You must provide four arguments to identify it as an error-handling middleware function.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With