Express: Can not get req.params in router middleware

Created on 18 Jan 2017  Â·  9Comments  Â·  Source: expressjs/express

// 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({})。

4.x question

Most helpful comment

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

All 9 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

snowdream picture snowdream  Â·  3Comments

nove1398 picture nove1398  Â·  3Comments

HafidAbnaou picture HafidAbnaou  Â·  3Comments

ER-GAIBI picture ER-GAIBI  Â·  3Comments

wxs77577 picture wxs77577  Â·  3Comments