如何使用Joi验证具有相同模式但没有限制dept的嵌套对象



假设我在下面的模式中有一个嵌套对象,我想用Joi验证它

{
"AND": [
{ "key": "", "value": "" },
{ "key": "", "value": "" },
{ "OR": [
{ "key": "", "value": "" },
{ "key": "", "value": "" },
{ "AND": [
{ "key": "", "value": "" },
{ "key": "", "value": "" },
...
]
},
...
],
...
]
}

这是我的V.1,它只允许1级深度:

const obj = Joi.object().keys({
key: Joi.string(),
value: Joi.string(),
});
obj.keys({
AND: Joi.array().items(obj),
OR: Joi.array().items(obj),
}).nand('AND', 'OR');
const nested = Joi.object()
.keys({
AND: Joi.array().items(obj),
OR: Joi.array().items(obj),
})
.nand('AND', 'OR');

这里的V.2只允许2级深度:

const obj = Joi.object().keys({
key: Joi.string(),
value: Joi.string(),
AND: Joi.array().items(Joi.object({ key: Joi.string(), value: Joi.string() })),
OR: Joi.array().items(Joi.object({ key: Joi.string(), value: Joi.string() })),
});

const nested = Joi.object()
.keys({
AND: Joi.array().items(obj),
OR: Joi.array().items(obj),
})
.nand('AND', 'OR');

有人能给我推荐正确的方法吗?

谢谢

您的两次尝试都是一个很好的开始,但正如您所发现的,模式的递归性质很难处理。

值得庆幸的是,Joi用.link():解决了这个问题

链接到另一个模式节点并重用它进行验证,通常用于创造性递归模式。。。

我们还可以使用.pattern()来避免重复ANDOR的规则。

我发现以下模式有效:

// attempt to match one of these schemas
Joi.alternatives([
// an object containing the key AND or OR where it's value matches 
// this entire schema definition
Joi.object().pattern(/^(AND|OR)$/, Joi.array().items(Joi.link('#schema'))),
// an object containing a key/value pair
Joi.object().keys({
key: Joi.string(),
value: Joi.string()
})
// we identify our schema with an ID so we can reference it in Joi.link()
]).id('schema')

带测试数据:

{
"AND": [
{ "key": "", "value": "" },
{ "key": "", "value": "" },
{
"OR": [
{ "key": "", "value": "" },
{ "key": "", "value": "" },
{
"AND": [
{ "key": "", "value": "" },
{ "key": "", "value": "" }
]
}
]
}
]
}

你可以在这里测试一下。

--

对于那些使用Joi版本<v16不支持link(),您可以使用lazy()

const schema = Joi.alternatives([
Joi.object().pattern(/^(AND|OR)$/, Joi.array().items(Joi.lazy(() => schema))),
Joi.object().keys({
key: Joi.string(),
value: Joi.string()
})
]);

相关内容

  • 没有找到相关文章