10

我正在尝试使用 Joi 验证 RESTful Web 服务接受的数据模型。

对于创建操作,我想对字段强制执行“必需”验证。但是,对于更新操作,可能会提交部分数据对象,因此我希望忽略“必需”属性。

除了创建两个模式之外,有没有办法实现这一点?

4

5 回答 5

4

您可以通过使用optionalKeys扩展第一个模式来避免这两种模式。

const createSchema = Joi.object().keys({
  name: Joi.string().required(),
  birthday: Joi.date().required(),
});

const updateSchema = createSchema.optionalKeys("name", "birthday");

Joi.validate({name: "doesn't work"}, createSchema); // error: birthday field missing
Joi.validate({name: "it works"}, updateSchema); // all good
于 2019-03-16T18:07:06.920 回答
4

.fork()你可以传入一个你想要的字段数组。

const validate = (credentials, requiredFields = []) => {

  // Schema
  let userSchema = Joi.object({
    username: Joi.string(),
    email: Joi.string().email(),
  })

  // This is where the required fields are set
  userSchema = userSchema.fork(requiredFields, field => field.required())

  return userSchema.validate(credentials)
}

validate(credentials, ['email'])

或者做相反的事情并将它们更改为可选。

于 2019-11-07T18:20:41.637 回答
1

alter使用该方法可以达到您想要的结果。这是一个例子。

const validateUser = (user, requestType) => {
  let schema = Joi.object({
    email: Joi.string().email().required(),
//Here, we want to require password when request is POST. 
//Also we want to remove password field when request is PUT
    password: Joi.string()
      .min(1)
      .max(256)
      .alter({
//For POST request
        post: (schema) => schema.required(),
//For PUT request
        put: (schema) => schema.forbidden(),
      }),
  });

  return schema.tailor(requestType).validate(user);
};

然后在我们的路由中,我们调用函数并传递参数,如下所示:

//For POST
const { error } = validateUser({email: "me@mail.com"}, "post");//error: "password is a required field" 
//For PUT 
const { error } = validateUser({email: "me@mail.com"}, "put");//error: undefined (no error)
于 2021-03-28T20:21:02.413 回答
0

根据条件使用.when()和设置。.required()

于 2015-07-09T13:51:44.733 回答
0

您可以通过将 Joi.string()... 替换为您作为用户名传递的确切值来跳过 Joi 验证。在示例中,我已将空用户名传递给 api。

同样在条件基础上,您可以跳过 joi 验证

let userSchema = Joi.object({
   username: "",
   email: <some condition> === true ? "" : Joi.string().required()
})
于 2020-09-09T15:25:52.563 回答