【问题标题】:Is using Joi for validation on top of Mongoose good practice?是否在 Mongoose 良好实践的基础上使用 Joi 进行验证?
【发布时间】:2019-08-25 23:10:13
【问题描述】:

我正在使用 Node.js、Mongoose 和 Koa 开发一个 RESTful API,但对于架构和输入验证方面的最佳实践,我有些困惑。

目前,我对每个资源都有 Mongoose 和 Joi 模式。 Mongoose 模式仅包含有关特定资源的基本信息。示例:

const UserSchema = new mongoose.Schema({
  email: {
    type: String,
    lowercase: true,
  },
  firstName: String,
  lastName: String,
  phone: String,
  city: String,
  state: String,
  country: String,
});

Joi 架构包含有关对象每个属性的详细信息:

{
  email: Joi.string().email().required(),
  firstName: Joi.string().min(2).max(50).required(),
  lastName: Joi.string().min(2).max(50).required(),
  phone: Joi.string().min(2).max(50).required(),
  city: Joi.string().min(2).max(50).required(),
  state: Joi.string().min(2).max(50).required(),
  country: Joi.string().min(2).max(50).required(),
}

Mongoose 模式用于在写入数据库时​​在端点处理程序级别创建给定资源的新实例。

router.post('/', validate, routeHandler(async (ctx) => {
  const userObj = new User(ctx.request.body);
  const user = await userObj.save();

  ctx.send(201, {
    success: true,
    user,
  });
}));

Joi 模式在验证中间件中用于验证用户输入。每个资源我有 3 种不同的 Joi 模式,因为允许的输入因请求方法(POST、PUT、PATCH)而异。

async function validate(ctx, next) {
  const user = ctx.request.body;
  const { method } = ctx.request;
  const schema = schemas[method];

  const { error } = Joi.validate(user, schema);

  if (error) {
    ctx.send(400, {
      success: false,
      error: 'Bad request',
      message: error.details[0].message,
    });
  } else {
    await next();
  }
}

我想知道我目前在 Mongoose 之上使用多个 Joi 模式的方法是否最佳,考虑到 Mongoose 也具有内置的 int 验证。如果没有,有哪些好的做法可以遵循?

谢谢!

【问题讨论】:

  • 您能简要解释一下为什么要同时使用这两种方法吗?毕竟,Mongoose 模式非常强大,您可以在不使用 joi 的情况下对输入执行复杂的验证。
  • 我考虑过将 Joi 验证作为请求级别的中间件,因为 Mongoose 似乎只在您创建/保存对象时提供应用级别的验证。
  • 能否详细说明应用级和请求级的区别?
  • 通过请求级别,我的意思是在收到请求时以及在执行其端点逻辑之前。这意味着如果输入没有通过验证中间件,请求可以立即终止。应用程序级别是指在执行端点逻辑时。因此,请求会通过所有中间件,并且当对象即将在数据库中更新时验证输入。
  • @omer 都是一样的。对吗?

标签: node.js rest mongoose koa joi


【解决方案1】:

即使您有猫鼬模式,实现验证服务也是一种常见的做法。正如您自己所说,在对数据执行任何登录之前,它将返回一个验证错误。因此,在这种情况下肯定会节省一些时间。 此外,您可以使用 joi 获得更好的验证控制。但是,这在很大程度上取决于您的要求,因为它会增加您必须编写的额外代码,这可以避免,而不会对最终结果产生太大影响。

【讨论】:

    【解决方案2】:

    IMO,我认为这个问题没有明确的答案。就像@omer 在上面的评论部分所说的那样,Mongoose 强大到足以站稳脚跟。

    但是,如果您的代码在接收输入后的逻辑/操作非常繁重且昂贵,那么在 API 层中添加额外的保护以防止您的繁重代码运行不会有什么坏处。

    编辑:我刚刚发现这个不错的 answer 是由一位受人尊敬的人写的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 2022-06-30
      • 1970-01-01
      • 2020-04-02
      • 2021-05-23
      • 2023-03-21
      相关资源
      最近更新 更多