JSON Schema校验返回冗余验证消息的原因及调整方案
1. 第一版oneOf Schema返回冗余校验错误的原因
oneOf关键字的校验逻辑是:待校验实例必须恰好匹配数组中的一个子Schema,只要匹配数量为0或大于1,就会判定校验失败。
当传入{"relatedParty": "tr13", "action": "b"}时:
- 第一个子Schema要求
action字段值匹配正则a,实际值为b不满足,校验失败,抛出action字段的pattern错误 - 第二个子Schema要求
relatedParty字段值匹配正则er\d{3},实际值为tr13不满足,校验失败,抛出relatedParty字段的pattern错误
两个分支全部匹配失败时,校验器会默认返回所有分支下的全部错误条目,不会自动识别你预期匹配的分支,因此会出现冗余的错误提示。
另外第一版Schema的正则没有加起止符^/$,会出现tr123abc、xer127这类部分匹配的值误通过的问题。
2. 实现精准校验的正确Schema写法
你第二版Schema不生效的核心原因是:$defs只是用来存储可复用规则的命名空间,里面定义的规则不会自动执行,你没有在当前对象的校验逻辑中引用tr-requires-action规则,所以条件校验根本没有触发。
调整后的可精准报错的Schema如下:
{ "type": "array", "maxItems": 4, "items": { "type": "object", "required": ["relatedParty"], "properties": { "relatedParty": { "type": "string", "oneOf": [ { "pattern": "^tr\\d{2}$" }, { "pattern": "^er\\d{3}$" } ] }, "action": { "type": "string" } }, "if": { "properties": { "relatedParty": { "pattern": "^tr\\d{2}$" } }, "required": ["relatedParty"] }, "then": { "required": ["action"], "properties": { "action": { "pattern": "^a$" } } }, "else": { "not": { "required": ["action"] } } } }
这个写法的校验逻辑:
- 基础校验层先校验
relatedParty的格式,格式不对直接返回对应字段错误,不会进入后续条件分支 - 当
relatedParty匹配tr+两位数字规则时,才会触发action字段的必填和值格式校验,此时如果action值不符合要求,只会返回action对应的单条错误 - 当
relatedParty匹配er+三位数字规则时,会禁止传入action字段,避免冗余字段 - 所有正则补充了起止匹配符,避免部分匹配导致的漏校验
内容的提问来源于stack exchange,提问作者Idur Jul
相关产品推荐
相关产品推荐

