Joi 根据多个密钥验证备选方案
Joi to validate alternatives depending on multiple keys
使用 Joi,如何使架构仅在 type
为 A
或 B
AND subType
时才需要 rent.max
是 AA
还是 BB
?这是我的尝试。
const Joi = require("joi");
const schema = Joi.object().keys({
type: Joi.string().valid('A', 'B', 'C').required(),
subType: Joi.string().valid('AA', 'BB', 'X'),
rent: Joi.object().keys({
price: Joi.number().required().precision(2),
// max is allowed only when type is A or B
// and subType is AA or BB.
max: Joi.alternatives()
.when('type', {
is: Joi.valid('A', 'B'),
then: Joi.alternatives().when('subType', {
is: Joi.valid('AA', 'BB'),
then: Joi.number(),
otherwise: Joi.forbidden()
}),
otherwise: Joi.forbidden()
})
})
});
const obj = {
type: 'A',
subType: 'AA',
rent: {
price: 3000.25,
max: 300.50,
}
};
const result = Joi.validate(obj, schema);
console.log(result.error);
我预计验证会失败,但事实并非如此。
如果你想验证键 type 和 subType 你的验证必须在对象之后,例如:
const schema = Joi.object({
type: Joi.string().valid('A', 'B', 'C'),
subType: Joi.string().valid('AA', 'BB', 'X'),
rent: Joi.object({
amount: Joi.number(),
price: Joi.number().required().precision(2),
})
}).when(Joi.object({
type: Joi.string().valid('A', 'B').required(),
subType: Joi.string().valid('AA', 'BB').required()
}).unknown(), {
then: Joi.object({
rent: Joi.object({
amount: Joi.number().required()
})
}),
otherwise: Joi.object({
rent: Joi.object({
amount: Joi.forbidden()
})
})
});
这是以下示例的结果:
// FAIL - requires amount
const obj = {
type: 'A',
subType: 'BB',
rent: {
price: 10
}
};
// FAIL - amount is not allowed
const obj = {
type: 'A',
subType: 'X',
rent: {
amount: 3000.25,
price: 300.50
}
};
// SUCCESS
const obj = {
type: 'A',
subType: 'BB',
rent: {
amount: 3000.25,
price: 300.50
}
};
// SUCCESS
const obj = {
type: 'A',
subType: 'X',
rent: {
price: 300.50
}
};
使用 Joi,如何使架构仅在 type
为 A
或 B
AND subType
时才需要 rent.max
是 AA
还是 BB
?这是我的尝试。
const Joi = require("joi");
const schema = Joi.object().keys({
type: Joi.string().valid('A', 'B', 'C').required(),
subType: Joi.string().valid('AA', 'BB', 'X'),
rent: Joi.object().keys({
price: Joi.number().required().precision(2),
// max is allowed only when type is A or B
// and subType is AA or BB.
max: Joi.alternatives()
.when('type', {
is: Joi.valid('A', 'B'),
then: Joi.alternatives().when('subType', {
is: Joi.valid('AA', 'BB'),
then: Joi.number(),
otherwise: Joi.forbidden()
}),
otherwise: Joi.forbidden()
})
})
});
const obj = {
type: 'A',
subType: 'AA',
rent: {
price: 3000.25,
max: 300.50,
}
};
const result = Joi.validate(obj, schema);
console.log(result.error);
我预计验证会失败,但事实并非如此。
如果你想验证键 type 和 subType 你的验证必须在对象之后,例如:
const schema = Joi.object({
type: Joi.string().valid('A', 'B', 'C'),
subType: Joi.string().valid('AA', 'BB', 'X'),
rent: Joi.object({
amount: Joi.number(),
price: Joi.number().required().precision(2),
})
}).when(Joi.object({
type: Joi.string().valid('A', 'B').required(),
subType: Joi.string().valid('AA', 'BB').required()
}).unknown(), {
then: Joi.object({
rent: Joi.object({
amount: Joi.number().required()
})
}),
otherwise: Joi.object({
rent: Joi.object({
amount: Joi.forbidden()
})
})
});
这是以下示例的结果:
// FAIL - requires amount
const obj = {
type: 'A',
subType: 'BB',
rent: {
price: 10
}
};
// FAIL - amount is not allowed
const obj = {
type: 'A',
subType: 'X',
rent: {
amount: 3000.25,
price: 300.50
}
};
// SUCCESS
const obj = {
type: 'A',
subType: 'BB',
rent: {
amount: 3000.25,
price: 300.50
}
};
// SUCCESS
const obj = {
type: 'A',
subType: 'X',
rent: {
price: 300.50
}
};