JSON Schema数组项验证不生效问题排查
分析与解决方案:JSON Schema验证未按预期失败的问题
我来帮你拆解下问题所在——你的验证没按预期触发失败,核心原因是JSON Schema的默认行为和你的payload结构不匹配,咱们一步步理清楚:
问题根源
你当前的JSON Schema定义中,include是一个对象,仅对其中的values数组做了项限制,但两个默认规则导致了不符合预期的验证结果:
values不是必填字段(Schema里未添加required: ["values"]),所以当payload里的include没有values时,这部分数组验证逻辑根本不会执行;- JSON Schema默认允许对象存在额外属性(
additionalProperties默认值为true),所以include里的merchant_channel、merchant这些未在Schema中定义的属性会被直接放行。
这两个因素叠加,就导致不符合预期的payload通过了验证。
两种修正方案(根据实际需求选择)
方案1:保持payload结构,严格限制include规则
如果你确实需要include是一个对象,且必须包含values数组(数组项只能是"language"),同时不允许存在其他额外属性,修改你的JSON Schema如下:
{ "type": "object", "properties": { "query_string": { "type": "object", "properties": { "include": { "type": "object", "properties": { "values": { "type": "array", "items": { "type": "string", "enum": ["language"] } } }, // 强制要求include必须包含values字段 "required": ["values"], // 禁止include存在Schema未定义的额外属性 "additionalProperties": false } } } } }
修改后,当payload里的include缺少values、存在额外属性,或者values数组包含非"language"的项时,验证都会按预期失败。
方案2:修正payload结构,让include直接作为目标数组
如果你实际想验证的是include本身就是一个数组(而非包含数组的对象),需要同时调整payload和Schema:
- 调整后的PHP payload:
$payload = (object) []; $payload->query_string = (object) []; // 将include改为数组类型 $payload->query_string->include = ["merchant_channel", "merchant"];
- 对应的JSON Schema:
{ "type": "object", "properties": { "query_string": { "type": "object", "properties": { "include": { "type": "array", "items": { "type": "string", "enum": ["language"] } } } } } }
此时,当include数组包含"merchant_channel"这类不在枚举范围内的值时,验证就会触发失败。
补充说明
justinrainbow/json-schema严格遵循JSON Schema规范,记住两个关键默认行为可以避免类似问题:
- 对象的
additionalProperties默认值为true,允许任意未定义的属性; - 所有属性默认非必填,除非在
required数组中声明。
内容的提问来源于stack exchange,提问作者mikelovelyuk
相关产品推荐
相关产品推荐

