JSON Schema嵌套结构变更后allOf条件校验失效问题排查
问题根因
核心错误是JSON Schema所有校验规则的路径都是相对于当前挂载规则的节点的相对路径,而非全局根路径。
你将OFFER条件校验通过allOf挂载在$defs/Header节点下,此时if/then块的校验对象是Header实例本身,规则内写的properties.Transaction路径,实际是尝试从Header对象下查找名为Transaction的子属性——但Header对象下只有Flow属性,不存在Transaction字段,直接导致if条件永远判定为不匹配,then块的强制校验逻辑完全不触发,本该拦截的无效实例就会被误判为有效。
修正方案
跨关联字段的条件校验,必须挂载到两个字段的最近共同祖先节点上,同时调整规则内的相对路径匹配实际层级:
- 把原来挂在Header节点
allOf里的OFFER规则引用,移到Transaction节点的allOf下。Flow位于Transaction.Header路径下,Offer位于Transaction.Offer路径下,Transaction是两个字段的最近共同父节点 - 调整OFFER规则里
if/then块的路径配置,去掉最外层冗余的Transaction层级,直接匹配当前节点(即Transaction实例)下的Header和Offer属性
修正后的核心Schema片段如下:
{ "$defs": { "Transaction": { "type": "object", "additionalProperties": false, "properties": { "Header": { "$ref": "#/$defs/Header" }, "Offer": { "$ref": "#/$defs/Offer" } }, "required": ["Header"], "title": "Transaction", // 条件校验移到共同父节点下 "allOf": [ { "$ref": "#/$defs/OFFER" } ] }, "Header": { "type": "object", "additionalProperties": false, "properties": { "Flow": { "$ref": "#/$defs/Flow" } } // 移除原挂载在此处的层级错误的OFFER引用 }, "OFFER": { "if": { "type": "object", "properties": { // 相对路径从当前Transaction节点开始,直接匹配Header属性 "Header": { "type": "object", "properties": { "Flow": { "enum": ["Offer"] } }, "required": ["Flow"] } }, "required": ["Header"] }, "then": { "type": "object", "properties": { // 相对路径从当前Transaction节点开始,直接匹配Offer属性 "Offer": { "type": "object", "properties": { "Offer-Status": { "enum": ["NEW"] } }, "required": ["Offer-Status"] } }, "required": ["Offer"] } } } }
校验效果验证
调整后规则完全符合预期:
- 当
Transaction.Header.Flow取值为"Offer"时,if条件命中,会强制要求Transaction.Offer存在,且Offer-Status必须为"NEW",你提供的缺少Offer-Status的测试JSON会被正确判定为无效 - 当Flow取值为
"Acceptance"时,if条件不命中,不会触发Offer相关的强制校验,不会干扰其他流程的校验逻辑
内容的提问来源于stack exchange,提问作者Croz
相关产品推荐
相关产品推荐

