Reputation: 15
I am writing APIs and wanted to understand what is a good way to add middleware shared by multiple routes. The middlewares does the same things in each route, like validating hosts/ip, validate user, etc. The req object gets loaded with other objects in each of the middlewares like req.host, req.ip, req.username etc.
app.post("/route1", middleware1, middleware2, middleware3, middleware4);
app.post("/route2", middleware1, middleware2, middleware3, middleware4);
const middleware1 = (req, res, next) => {
// does something to validate user
req.username = "username"
next();
}
const middleware2 = (req, res, next) => {
// host validation
req.host = "something modified in validation"
next();
}
const middleware3 = (req, res, next) => {
// checks for mac and ip
req.mac = "mac addr"
next();
}
const middleware4 = (req, res, next) => {
res.send();
}
Or something like this:
app.post("/route1", middleware1);
app.post("/route2", middleware1);
const middleware1 = (req, res) => {
// does something to validate user
req.username = "username"
middleware2(req, res);
}
const middleware2 = (req, res) => {
// host validation
req.host = "something modified in validation"
middleware3(req, res);
}
const middleware3 = (req, res) => {
// checks for mac and ip
req.mac = "mac addr"
middleware4(req, res);
}
const middleware1 = (req, res) => {
res.send();
}
Thanks.
Upvotes: 0
Views: 5030
Reputation: 4457
You can specify multiple middlewares, see the app.use docs:
An array of combinations of any of the above.
You can create a file of all middlewares like -
middlewares.js
module.exports = [
function(req, res, next){...},
function(req, res, next){...},
function(req, res, next){...},
.
.
.
function(req, res, next){...},
]
and as then simply add it like:
/*
you can pass any of the below inside app.use()
A middleware function.
A series of middleware functions (separated by commas).
An array of middleware functions.
A combination of all of the above.
*/
app.use(require('./middlewares.js'));
Note - Do this only for those middlewares which will be common for all such requests.
Upvotes: 0
Reputation: 1208
const express = require('express')
const { routesMiddleware } =require('./middlewares')
const { pureVaidationsFunctions1 } =require('./services')
const rout1 =express.Router()
const rout2 =express.Router()
const app = express()
app.use('/route1',route1)
app.use('/route2',route2)
// routesMiddleware a middleware to handle the execution of list of functions
// pureVaidationsFunctions1 list of funtions that `routesMiddleware` will consume
route1.post(routesMiddleware(pureVaidationsFunctions1))
route2.post(routesMiddleware(pureVaidationsFunctions2))
make sense?
Upvotes: 0
Reputation: 113876
Generally I wouldn't call middlewares directly from another middleware. It mixes responsibilities of middleware logic and where the middleware is used.
Express is much more configurable than you think though. You can also install common middlewares in common paths:
If all routes use the middlewares:
// How common middlewares are normally installed:
app.post(middleware1);
app.post(middleware2);
app.post(middleware3);
app.post(middleware4);
// Alternative, less common way to do it:
app.post(middleware1,middleware2,middleware3,middleware4);
If only a specific pattern of urls use the middlewares:
// Use a regexp:
app.post(/route(1|2)/, middleware1, middleware2, middleware3, middleware4);
// Or if you don't like regexp, use globs:
app.post('route*', middleware1, middleware2, middleware3, middleware4);
// Or a more specific glob pattern:
app.post('route1?2?', middleware1, middleware2, middleware3, middleware4);
If all url in a subpath use the middlewares. For example, lets say if all urls in /route/...
use the middlewares:
const route = express.Router();
app.use('/route',route);
route.post(middleware1);
route.post(middleware2);
route.post(middleware3);
route.post(middleware4);
If none of the above appeal to you you can still use your second option but instead of calling middlewares inside each other you write a middleware to initialize middlewares:
function commonMiddlewares (req, res, next) {
middleware1(req,res,function() {
middleware2(req,res,function() {
middleware3(req,res,function() {
middleware4(req,res,next);
});
});
});
}
Which can be written in a less nested way:
function commonMiddlewares (req, res, next) {
function runMiddleware4 () {
middleware4(req,res,next);
}
function runMiddleware3 () {
middleware3(req,res,runMiddleware4);
}
function runMiddleware2 () {
middleware2(req,res,runMiddleware3);
}
middleware1(req,res,runMiddleware2);
}
Upvotes: 3