快速路由:使用router.use / all和router.param控制流

时间:2020-01-22 19:43:04

标签: express express-router

我想使用这类中间件来验证参数。问题是router.param总是在第一个中间件router.all之前应用(我也尝试过router.use,它不起作用,因为param对两个中间件都通用)。是否可以在router.param之前执行中间件1?

// Middleware 1
router.all('/:firstId/checklist/:**secondId**/*',
  (req, res, next) => {
     console.log('Request matched')
     next()
  },  
param('**secondId**', "Error message 2")
    .isMongoId(),
  checkValidationErrors
)

router.param('**secondId**', callback)

但是,中间件1不能按我预期的那样工作。如果参数是有效的MongoDB ObjectId,则记录'Request matched',根据请求相应地应用下一个中间件。如果它不是有效的ID,则记录'Request matched' NOT ,则响应中发送的预期错误为 NOT 。我从router.param的Mongoose那里得到了这个错误:

MongooseError [CastError]: Cast to ObjectId failed for value "xxx" at path "_id" for model "XXX"                 

我试图评论router.param,它解决了问题。因此,它当然与执行顺序有关。

非常感谢您的帮助

2 个答案:

答案 0 :(得分:0)

将其翻转(在您的情况下,原因是在两种情况下都只查找:firstId/*,因为它同时适合两种情况。如果第一个模式/路径与输入URI匹配,则不会查找)用于您的中间件2。

// Middleware 1
router.all('/:firstId/*',
  param('firstId', "Error message 1")
    .isMongoId(),
  checkValidationErrors        
)

// Middleware 2
router.all('/:firstId/checklist/:secondId/*',
  (req, res, next) => {
     console.log('Request matched')
     next()
  },  
param('secondId', "Error message 2")
    .isMongoId(),
  checkValidationErrors
)

收件人

// Middleware 2
router.all('/:firstId/checklist/:secondId/*',
  (req, res, next) => {
     console.log('Request matched')
     next()
  }, 

param('secondId', "Error message 2")
    .isMongoId(),
  checkValidationErrors
)

// Middleware 1
router.all('/:firstId/*',
  param('firstId', "Error message 1")
    .isMongoId(),
  checkValidationErrors        
)

答案 1 :(得分:0)

我找不到一种使用与router.param相同参数的中间件并在router.param之前执行的方法,因为router.param似乎是首先被系统地执行。但是,有一种解决方法可以做到这一点:将要执行的中间件重新分组到router.param之前的单独文件中。

代替: app.js(主应用程序文件)路由到originalRouter(原始路由器文件)。

控制流程应为: app.js(主应用程序文件)路由到beforeParamMiddlewwareRouter,路由到originalRouter(原始路由器文件)

OR

在app.js中:

app.use('/path', beforeParamMiddlewwareRouter, originalRouter)

如果有的话,随时提供更好的解决方案。我愿意接受建议。