如何将数据从快速验证中间件传递到下一个函数?

问题描述

我有一个类似这样的 express 应用。

const app = require('express')();

// Task model
const Task = require('./models/Task');
const { param,validationResult } = require('express-validator');

const getTaskValidations = [
  param('id')
    .custom(async (id,{ req }) => {
      try {
        const task = await Task.findOne({ _id: id,user: req.user.id });
        if (!task) Promise.reject('Task not found');
      } catch (err) {
        // Handle error
      }
    })
]

const validate = (req,res,next) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(401).json({ message: errors.array()[0].msg });
  }
  next();
}

// Get Task by id
app.get('/tasks/:id',getTaskValidations,validate,async (req,res) => {
  try {
    const task = await Task.findById(req.params.id);
    res.json(task)
  } catch (err) {
    // Handle err
  }
})

我想通过 id 获取任务。在 GET tasks/:id 中,req.params.id 将包含任务的 ID。
任务模型看起来像这样

{
  id: 
  task: 
  user:
}

通过查看端点,很明显我正在传递两个中间件。 第一个中间件 getTaskValidations 将检查任务是否会给出 id 和 req.user 是否存在。 第二个中间件 validate 将检查错误。 然后再次将查询数据库的任务并将数据发送到客户端,导致 2 个数据库查询。 如何重用在 task 中间件中获得的相同 getTaskValidations

解决方法

您可以将从查询中获得的响应存储在请求 (req) 中。

const task = await Task.findOne({ _id: id,user: req.user.id });
if (task) 
     req.task = task;
else 
     Promise.reject('Task not found');

稍后,在 API 端点中,您可以简单地使用

app.get('/tasks/:id',getTaskValidations,validate,async (req,res) => {
  try {
    const task = req.task;
    res.json(task)
  } catch (err) {
    // Handle err
  }
});

获取task中间件中获取的getTaskValidations

,

您可以像这样将查询结果添加到 req.body.task 中

const getTaskValidations = [
  param('id')
    .custom(async (id,{ req }) => {
      try {
        const task = await Task.findOne({ _id: id,user: req.user.id });
        req.body.task = task
        if (!task) Promise.reject('Task not found');
      } catch (err) {
        // Handle error
      }
    })
]

在控制器中

app.get('/tasks/:id',res) => {
  try {
    let {task} = req.body
    res.json(task)
  } catch (err) {
    // Handle err
  }
})