【问题标题】:Ignoring "required" in Joi validation?在 Joi 验证中忽略“必需”?
【发布时间】:2015-08-03 16:51:47
【问题描述】:

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

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

除了创建两个模式之外,还有其他方法可以实现吗?

【问题讨论】:

  • 你能删除required吗?
  • 在创建过程中,我想强制执行required。由于缺少在验证期间忽略 required 的选项,我想我可能需要创建两个架构——一个用于创建,另一个用于更新。

标签: javascript validation joi


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您可以通过使用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
    

    【讨论】:

    • 我认为 optionalKeys() 现在已弃用 - .fork() 将是执行此操作的新方法。
    【解决方案3】:

    使用.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'])
    

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

    【讨论】:

      【解决方案4】:

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

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

      let userSchema = Joi.object({
         username: "",
         email: <some condition> === true ? "" : Joi.string().required()
      })
      

      【讨论】:

        【解决方案5】:

        使用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)
        

        【讨论】:

          猜你喜欢
          • 2019-03-23
          • 1970-01-01
          • 2020-05-04
          • 1970-01-01
          • 2022-08-18
          • 2018-01-18
          • 1970-01-01
          • 2015-03-26
          • 1970-01-01
          相关资源
          最近更新 更多