ExpressJS:Router.param()&的中间件控制流程。 Router.use()

时间:2014-12-31 02:53:36

标签: node.js express middleware

在我的Express.js应用程序中,我有一些自定义验证和参数解析。对于我的一条路线,我期待obj_id作为路线的一部分提供。如果mongoose无法在DB中找到具有该ID的obj,则返回404错误。鉴于我在router.use调用之前调用了router.param,我希望先执行param验证。但是,使用node-inspector,我能够验证在自定义中间件之前没有访问param函数。

如何在中间件之前执行param解析?

请注意,此中间件正在多个功能上使用,因此我不想将其添加到路由器调用中。

router.param('obj', function(req, res, next, id){
  Obj.findOne({_id: id}, function(err, obj){
    if (err || !obj) {
      res.status(404).json({error: {message: "No obj with that ID", type: "bad_parameters.unknown_obj"}});
    } else {
      req.obj = obj;
      next();
    }
  });
});

router.use(function(req,res,next){
  ...
  //Do some validations
  ...
  if(error) return res.status(400).json(error);
  next();
});
...
//Other routes that are working well
...
router.get('/:obj', obj);

预期错误:

404 {error: {message: "No obj with that ID", type: "bad_parameters.unknown_obj"}}

实际错误:

400 {error: {message: "Validation failed", type: "bad_parameters"}}

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

您正在使用router.use()附加到中间件堆栈,并且只要路由器在其定义的路由上被请求触发,就会按其声明顺序执行。

如果将router.use()替换为router.all(),它将在router.param()之后执行。 所以你可以这样做:

router.route('/:obj')
            .all(validationMiddleware)
            .get(getHandler);
router.param('obj', resolveObj);