如何用Joi验证数组中仅存在一个isCreator为true的元素
Joi验证:确保people数组仅存在一个isCreator为true的元素
需求
验证对象中的people数组必须存在,且数组内恰好有一个元素的isCreator属性为true。
示例数组
符合要求的示例(仅1个创建者)
const first = { class: 'XYZ', people: [{ id: 1, name: "John", isCreator: false }, { id: 2, name: "Alex", isCreator: true }] };
无创建者的示例(不符合要求)
const second = { class: 'XYZ', people: [{ id: 1, name: "John", isCreator: false }, { id: 2, name: "Alex", isCreator: false }] };
多创建者的示例(不符合要求,但当前验证通过)
const third = { class: 'XYZ', people: [{ id: 1, name: "John", isCreator: true }, { id: 2, name: "Alex", isCreator: true }] };
当前Joi Schema
const schema = Joi.object().keys({ class: Joi.string().required(), people: Joi.array().items( Joi.object().keys({ id: Joi.number().integer().positive().required(), name: Joi.string().alphanum().required(), isCreator: Joi.boolean().required() }) ).min(2) .has(Joi.object().keys({ id: Joi.number(), name: Joi.string(), isCreator: Joi.valid(true) // 仅检查存在性,不限制数量 })).required() });
当前验证结果
first验证成功(符合要求)second验证失败(无创建者,符合预期)third验证成功(存在2个创建者,不符合需求,需修复)
解决方案
添加自定义验证逻辑,统计people数组中isCreator为true的元素数量,确保恰好为1个。修改后的Schema如下:
const schema = Joi.object().keys({ class: Joi.string().required(), people: Joi.array().items( Joi.object().keys({ id: Joi.number().integer().positive().required(), name: Joi.string().alphanum().required(), isCreator: Joi.boolean().required() }) ) .min(2) .custom((value, helpers) => { // 统计isCreator为true的元素数量 const creatorCount = value.filter(person => person.isCreator).length; if (creatorCount !== 1) { // 返回自定义错误提示 return helpers.error('array.exactlyOneCreator', { count: creatorCount }); } return value; }) // 自定义错误消息 .messages({ 'array.exactlyOneCreator': 'people数组中必须恰好有一个isCreator为true的元素,当前数量为{{count}}' }) .required() });
验证结果修正
first验证成功(符合要求)second验证失败(错误提示:people数组中必须恰好有一个isCreator为true的元素,当前数量为0)third验证失败(错误提示:people数组中必须恰好有一个isCreator为true的元素,当前数量为2)
内容的提问来源于stack exchange,提问作者TalESid
相关产品推荐
相关产品推荐

