// hasProjectPremission List this
hasProjectPremission = (req, res, next) => {
console.log(req.params); // {}
next();
}
router.use(apiBiz.hasProjectPremission);
router.post('/:projId/api/new', apiBiz.createApi);
When request to the create api, I can't get req.params in hasProjectPremission, it's an empty object({})。
This is correct. The req.params is only available in the route which has actually declared parameters to put in there. A middleware has no route with parameters, so there is no way to understand what the parameters would be.
Depending on what you're trying to accomplish, you can write the above like
router.post('/:projId/api/new', apiBiz.hasProjectPremission, apiBiz.createApi);
This is a way to resolve it, but it's not simple. If I has more router path, I must write it many time.
If you have any thoughts about how to improve, please send a PR! There is no current other way to solve this for the reason I outlined above.
Okay, thank you.
I just came across this while looking for a solution for getting route params in the middleware. So according to this, if I want to apply a middleware that needs the req.params object, I'll have to apply that middleware individually to each route? I thought that if I had set mergeParams: true, I'm supposed to get the whole route.params object in the middleware.
I looked around the source and it seems a middleware skips parsing when there's no path associated. However, I don't think a middleware is executed unless it's part of the route handling stack, even if it's applied globally; which implicitly means there's a path/route associated with it. Not sure why is there a distinction between a global middleware vs a middleware that's part of a route explicitly.
If you have any thoughts about how to improve, please send a PR! There is no current other way to solve this for the reason I outlined above.
@afm-sayem If two same path bind different router, the router middleware will be shared, like this:
const router1 = express.Router();
const router2 = express.Router();
router1.use((req, res, next) => {
console.log('router1 middleware');
next();
});
router1.get('/test1', (req, res, next) => { res.send('router1'); });
router2.get('/test2', (req, res, next) => { res.send('router2'); });
app.use('/', router1);
app.use('/', router2);
When request to /test2, console also print router1 middleware
Actually middleware can get parameters from router, but it needs to know which one.
for example:
// handle any additional path with optional catch all
router.use('/:projId(\\d+)(/*)?', (req, res, next) => {
console.log(req.params); // { '0': undefined, '1': undefined, projId: '1337' }
next();
});
router.post('/:projId(\\d+)/api/new', (req, res) => res.sendStatus(200))
But IMO you should use router.param which will act like an middleware, executed right before route is handled.
router.param('projId', (req, res, next, projId) => {
// executes before route handler
next();
});
router.post('/:projId/api/new', (req, res) => res.send(req.params.projId)) // 1337
@aPoCoMiLogin Very thanks.
Most helpful comment
Actually middleware can get parameters from router, but it needs to know which one.
for example:
But IMO you should use router.param which will act like an middleware, executed right before route is handled.