Nit*_*esh 11 javascript node.js hapijs joi
我需要创建动态模式以根据请求查询中的键node js
使用Joi 验证器来验证我的 api请求查询。说下面提到的模式是我的有效查询。
我正在使用hapi/joi
版本16.1.8
组合1
{ type: 1, firstname: 'user first name', lastname: 'user last name'}
Run Code Online (Sandbox Code Playgroud)
组合2
{ type: 2 , salary: 1000, pension: 200}
Run Code Online (Sandbox Code Playgroud)
组合3
{ type: 3 , credit: 550, debit: 100}
Run Code Online (Sandbox Code Playgroud)
如您所见,对象键因 的值而异type
。如何正确处理?
我们可以使用Joi.alternatives处理两个条件,例如
const schema = Joi.alternatives().conditional(Joi.object({ type: 1 }).unknown(), {
then: Joi.object({
type: Joi.string(),
firstname: Joi.string(),
lastname: Joi.string()
}),
otherwise: Joi.object({
type: Joi.number(),
salary: Joi.any(),
pension: Joi.any()
})
});
Run Code Online (Sandbox Code Playgroud)
但是如何在 3 个条件下做到这一点?
Nit*_*esh 12
我以稍微不同的方式实现了相同的目标。在这里发布相同的内容,因为这可能对将来的某人有用。
const schema = Joi.object({
type: Joi.number().required().valid(1, 2, 3),
firstname: Joi.alternatives().conditional('type', { is: 1, then: Joi.string().required() }),
lastname: Joi.alternatives().conditional('type', { is: 1, then: Joi.string().required() }),
salary: Joi.alternatives().conditional('type', { is: 2, then: Joi.number().required() }),
pension: Joi.alternatives().conditional('type', { is: 2, then: Joi.number().required() }),
credit: Joi.alternatives().conditional('type', { is: 3, then: Joi.number().required() }),
debit: Joi.alternatives().conditional('type', { is: 3, then: Joi.number().required() }),
}))
Run Code Online (Sandbox Code Playgroud)
这正如预期的那样完美地工作。
当类型值为1
对象时,应该只有type
,firstname
并且lastname
当类型值为2
对象时,应该只有type
,salary
并且pension
当类型值为3
对象时,应该只有type
,credit
并且debit
任何其他组合都将从 joi 验证器中间件层作为错误抛出。此外,除 1、2 和 3 之外的任何其他类型值都将引发错误。
小智 9
我试图找到一种方法来做类似的事情。然后我就明白了。
const Joi = require('joi');
const schema = Joi.object({
type: Joi.number().valid(1,2,3),
// anything common
}).when(Joi.object({type: Joi.number().valid(1)}).unknown(), {
then: Joi.object({
firstname: Joi.string(),
lastname: Joi.string(),
})
})
.when(Joi.object({type: Joi.number().valid(2)}).unknown(), {
then: Joi.object({
salary: Joi.number(),
pension: Joi.number(),
})
})
.when(Joi.object({type: Joi.number().valid(3)}).unknown(), {
then: Joi.object({
credit: Joi.number(),
debit: Joi.number(),
})
});
Run Code Online (Sandbox Code Playgroud)
在文档中,它看起来switch
是可以一起使用的有效密钥alternatives.conditional
。您可以尝试以下操作吗?
const schema = Joi.alternatives().conditional(Joi.object({
type: 1
}).unknown(), {
switch: [{
is: 1,
then: Joi.object({
type: Joi.string(),
firstname: Joi.string(),
lastname: Joi.string(),
}),
}, {
is: 2,
then: Joi.object({
type: Joi.number(),
salary: Joi.any(),
pension: Joi.any(),
}),
}, {
// ...
}],
});
Run Code Online (Sandbox Code Playgroud)
编辑:
无法在任何地方找到有关使用关键字的任何示例switch
...
但在hapijs/joi github中找到了其他方法来实现它
const schema = Joi.object({
a: Joi.number().required(),
b: Joi.alternatives()
.conditional('a', [
{ is: 0, then: Joi.valid(1) },
{ is: 1, then: Joi.valid(2) },
{ is: 2, then: Joi.valid(3), otherwise: Joi.valid(4) }
])
});
Run Code Online (Sandbox Code Playgroud)
这个对我有用!
var Joi = require('joi');
var schema = {
a: Joi.any().when('b', { is: 5, then: Joi.required(), otherwise: Joi.optional() }),
b: Joi.any()
};
var thing = {
b: 5
};
var validate = Joi.validate(thing, schema);
// returns
{
error: null,
value: {
b: 5
}
}
Run Code Online (Sandbox Code Playgroud)
这是参考。