如何用AJV定义带数组元素条件必填属性的JSON Schema?
使用AJV定义满足依赖默认值的JSON Schema
需求回顾
需要验证一个包含defaults(可选)和entries(必填数组)的JSON结构,核心规则是:entries中每个对象的foo.bar/foo.baz是否必填,取决于defaults.foo中对应的字段是否存在。
最终Schema定义
{ "type": "object", "required": ["entries"], "properties": { "defaults": { "type": "object", "properties": { "foo": { "type": "object", "properties": { "bar": { "type": "string" }, "baz": { "type": "string" } }, "additionalProperties": false } }, "additionalProperties": false }, "entries": { "type": "array", "items": { "type": "object", "properties": { "foo": { "type": "object", "properties": { "bar": { "type": "string" }, "baz": { "type": "string" } }, "additionalProperties": false, "allOf": [ { "if": { "not": { "$data": "/defaults/foo/bar" } }, "then": { "required": ["bar"] } }, { "if": { "not": { "$data": "/defaults/foo/baz" } }, "then": { "required": ["baz"] } } ] }, "other": { "type": "number" } }, "required": ["foo"], "additionalProperties": true } } }, "additionalProperties": false }
关键细节说明
- 顶级规则:明确
entries为必填字段,defaults可选;限制顶级仅允许这两个字段(additionalProperties: false)。 - defaults结构:约束
defaults.foo仅能包含bar和baz两个字符串类型字段。 - entries数组验证:
- 每个数组项(entry)必须包含
foo字段,允许额外自定义字段(比如示例中的other)。 - 核心逻辑通过
allOf结合if-then实现:- 用
$data关键字引用顶级的/defaults/foo/bar,判断该字段是否不存在(not),如果是,则当前foo必须包含bar。 - 同理处理
baz字段的必填规则。
- 用
- 每个数组项(entry)必须包含
- AJV配置:需要在初始化AJV实例时启用
data选项,否则$data关键字无法生效:const Ajv = require('ajv'); const ajv = new Ajv({ data: true }); // 启用$data支持
验证场景示例
- 当
defaults.foo.bar存在时,entries中的foo.bar可省略; - 当
defaults.foo.bar不存在时,entries中的每个foo必须包含bar字段; entries可以是空数组,但不能缺失该字段。
内容的提问来源于stack exchange,提问作者jy95
相关产品推荐
相关产品推荐

