【问题标题】:joi validation based on array object property value基于数组对象属性值的 joi 验证
【发布时间】:2020-05-11 15:52:37
【问题描述】:

我有一组数据要验证:

{
   "createUser": {
     "isCustomer": true or false,
     "data": {
       "product": [ // sometimes array of object with id : 3
        {
         "id":46,
         "sumInsured":"4562000",
        },
        {
         "id":45,
         "sumInsured":"8532000",
        },
        ]
   }
}

以下是我们需要验证的场景:

1) validate array of objects
2) isCustomer is mandatory when id is 45
3) isCustomer not allowed when id is 3

首先完成:

Joi.object({
  data: Joi.array()
        .items({
          id: Joi.number().valid(3,45,46)
            .required(),
          sumInsured: Joi.string()
            .required()
        }),
})

我搜索了很多关于相同的内容,但仍然无法找到相同的解决方案。

任何帮助将不胜感激。

提前致谢。

【问题讨论】:

  • 老实说 - 这是一个相当复杂的嵌套模式 - 坦率地说,缺乏对 SO 的关注 - 我可以将第 2 点和第 3 点模式分开以进行各自的验证,但将它们组合起来不值 25 分。 .
  • @DenisTsoi 我尝试了解决方案,但问题是我尝试使用 id 3、46。它仍然要求 isCustomer。所以我尝试删除 isCustomer。必需,但即使我们传递不同的产品 ID,它仍然可以通过。
  • 您要求进行组合模式验证 - 这可能需要几个小时 - 老实说,这确实需要花费很多时间
  • @DenisTsoi 否未组合模式验证。仅当 id 为 45 时才强制设置 isCustomer,而不是当 id 为 3 或 46 时。

标签: javascript node.js hapijs joi


【解决方案1】:

这是第 2 点和第 3 点的组合模式。

您将需要使用方法.when - 这将定义您的第一个 如果条件。从那里,您将必须包含另一个 .when 以添加您的第二个 if 条件

这样

.when("data", {
  is: <first if condition>,
  then: <first if condition do something>
  otherwise: .when("data",{
    is: <else if>
    then: <else if do something>
  })
})

要从逻辑上理解上述内容, 这将导致以下结果

Joi.any().when("data", {
  is: <is id 45?>,
  then: <is required>
  otherwise: Joi.any().when("data",{
    is: <is id 3?>
    then: <is forbidden>
  })
})

测试用例

const test_id_3_ok = {
  createUser: {
    data: {
      product: [
        {
          id: 3,
        },
      ],
    },
  },
};

const test_id_46_ok = {
  createUser: {
    data: {
      product: [
        {
          id: 46,
        },
      ],
    },
  },
};

const test_id_46_has_customer_ok = {
  createUser: {
    isCustomer: true,
    data: {
      product: [
        {
          id: 46,
        },
      ],
    },
  },
};

const test_id_46_no_customer_ok = {
  createUser: {
    data: {
      product: [
        {
          id: 46,
        },
      ],
    },
  },
};


const test_id_3_has_customer_should_error = {
  isCustomer: true,
  createUser: {
    data: {
      product: [
        {
          id: 3,
        },
      ],
    },
  },
};

const test_id_45_ok = {
  createUser: {
    isCustomer: true,
    data: {
      product: [
        {
          id: 45,
        },
      ],
    },
  },
};

const test_id_45_no_customer_should_error = {
  createUser: {
    data: {
      product: [
        {
          id: 45,
        },
      ],
    },
  },
};

架构

const dataSchema = Joi.object({
  product: Joi.array().items(
    Joi.object({
      id: Joi.number().valid(3, 45, 46),
    })
  ),
});

const mandatory = (value) =>
  Joi.object({
    product: Joi.array().items(
      Joi.object({
        id: Joi.number().valid(value),
      })
    ),
  });

const schema = Joi.object({
  createUser: Joi.object({
    isCustomer: Joi.any().when("data", {
      is: mandatory(3),
      then: Joi.forbidden(),
      otherwise: Joi.any().when("data", {
        is: mandatory(45),
        then: Joi.bool().required(),
      }),
    }),

    data: dataSchema,
  }),
});

schema.validate(test_id_3_ok) //?
schema.validate(test_id_3_has_customer_should_error);  //?

schema.validate(test_id_45_ok); //?
schema.validate(test_id_45_no_customer_should_error); //?

schema.validate(test_id_46_ok); //?
schema.validate(test_id_46_has_customer_ok); //?
schema.validate(test_id_46_no_customer_ok); //?

【讨论】:

  • 感谢您的尝试。不幸的是,这对我不起作用。
  • 信息不足。 解释它是如何不起作用的
猜你喜欢
  • 2019-01-20
  • 1970-01-01
  • 1970-01-01
  • 2017-08-05
  • 2016-11-02
  • 2016-08-05
  • 2016-10-11
  • 2020-06-04
  • 1970-01-01
相关资源
最近更新 更多