如何解决验证 Joi - 所有数组元素都具有相同的嵌套值
我想使用 Joi 来验证传入的 JSON 请求对象,以便每个数组元素在路径 .runs[].results.type
处具有相同的值。如果有一个元素突出,则验证应该失败。类似于 .results.type
内 .runs[]
上的 array.unique
的反面。
将以下 JSON 想象为有效输入:
{
runs: [
{ results: { type: 'A',side: 'left' },meta: { createdBy: 3 } },{ results: { type: 'A',side: 'right' },meta: { createdBy: 1 } }
]
}
这应该会引发验证错误:
{
runs: [
{ results: { type: 'A',{ results: { type: 'B',meta: { createdBy: 1 } }
]
}
我尝试编写一个 Joi 模式,例如:
...
runs: Joi.array()
.min(1)
.items(
Joi.object()
.unknown()
.keys({
results: Joi.object()
.keys({
type: Joi.string()
.allow('A','B','C','D')
.valid(Joi.ref('....',{ in: true,adjust: runs => runs.map(run => run.results.type) }))
.required(),side: Joi.string().allow('left','right')
})
})
)
...
但这不起作用(我认为它以循环引用结束)。此外,即使它成功运行,我也不确定在提供两种差异类型 A
和 B
的情况下它是否真的会破坏验证。
解决方法
我想我找到了一种不使用自定义函数的优雅解决方案,尽管这将是解决这个问题的一个很好的方法!
Joi.object().keys({
runs: Joi.array().items(
Joi.object().keys({
results: Joi.object().keys({
type: Joi.string().valid(
Joi.ref('....0.results.type')
).required()
})
})
).has(
Joi.object().keys({
results: Joi.object().keys({
type: Joi.valid('A','B','C','D').required()
})
}))
})
它基于首先确定所有 runs[]
元素具有相同的 .results.type
值,然后断言 runs
数组 .has()
至少有一个元素具有 { {1}}来自.results.type
。
我学到的有趣的事情是,在 Joi 中,数组元素在 {'A','D'}
中用点索引,例如 .ref()
。
您需要使用 .some()
o .every()
函数,如果至少有 some 元素满足条件,或者如果 every strong> 元素完成条件:
1) 使用 .some()
:
const object1 = {
runs: [
{ results: { type: 'A',side: 'left' },meta: { createdBy: 3 } },{ results: { type: 'A',side: 'right' },meta: { createdBy: 1 } }
]};
const object2 = {
runs: [
{ results: { type: 'A',{ results: { type: 'B',meta: { createdBy: 1 } }
]};
let result1 = object1.runs.some(e => e.results.type !== 'A');
console.log(result1); // false
let result2 = object2.runs.some(e => e.results.type !== 'A');
console.log(result2); // true
2) 使用 .every()
:
const object1 = {
runs: [
{ results: { type: 'A',meta: { createdBy: 1 } }
]};
let result1 = object1.runs.every(e => e.results.type === 'A');
console.log(result1); // true
let result2 = object2.runs.every(e => e.results.type === 'A');
console.log(result2); // false
- 如果您不知道目标值(在本例中为 'A'),只需取第一个类型值 ->
runs[0].results.type
并用它替换 'A'。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。