Joi基于自身键值的条件验证实现问题及优化探讨
Joi自引用条件验证:同时支持UUIDv4与特定字符串
general 背景与需求
现有Joi Schema如下,仅允许UUIDv4格式的class_id值:
exports.updateSchema = Joi.object({ class_id: Joi.string().guid({ version: 'uuidv4' }).required(), });
现在需要修改Schema,让class_id同时接受特定字符串general,因此需要实现基于字段自身值的条件验证逻辑。
尝试过的无效方案
方案1:使用when结合自引用ref
尝试通过Joi.ref('.class_id')实现自引用条件判断,但未正常工作:
exports.updateSchema = Joi.object({ class_id: Joi.string().when( Joi.ref('.class_id'), { not: Joi.string().guid({ version: 'uuidv4' }), then: Joi.string().valid('general').required(), otherwise: Joi.string().guid({ version: 'uuidv4' }).required(), }, ), });
方案2:对象级when条件验证
尝试通过对象级的when条件分支定义Schema,但错误信息不符合预期:
exports.updateGradeParamsSchema = Joi.object({ class_id: Joi.string(), }).when(Joi.object({ class_id: 'general' }).unknown(), { then: Joi.object({ class_id: Joi.string().valid('general').required() }), otherwise: Joi.object({ class_id: Joi.string().guid({ version: 'uuidv4' }).required() }), });
当输入john-doe时,返回错误:
"class_id" must be a valid GUID
而预期错误应为:
"class_id" must be [general]
当前最优方案
目前采用alternatives().conditional实现的方案相对可行:
exports.updateSchema = Joi.object({ class_id: Joi.alternatives().conditional('class_id', { not: Joi.string().guid({ version: 'uuidv4' }), then: Joi.string().valid('general').required(), otherwise: Joi.string().guid({ version: 'uuidv4' }).required() }) });
该方式会匹配第一个符合条件的Schema并忽略后续分支,但存在缺点:
- 若输入UUIDv1格式的值,会触发第一个分支的错误提示:
"class_id" must be [general],而非预期的"class_id" must be a valid GUID
内容的提问来源于stack exchange,提问作者Blackjack
相关产品推荐
相关产品推荐

