You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

复用JSON Schema枚举定义对象属性的写法是否合规?

解决JSON Schema枚举复用导致跨库校验结果不一致的问题

场景说明

我需要把一组枚举值作为单一数据源,同时用来约束字符串类型的属性值,以及对象类型的属性键名,避免多处维护枚举带来的不一致。但实际测试时,不同的JSON Schema校验库给出了完全相反的校验结果,有的说数据有效,有的判定无效。

问题原因

核心是不同校验库对JSON Schema版本的支持不一样,尤其是在用枚举约束对象属性名这个场景下:

  • Draft 7及以上的Schema规范新增了propertyNames关键字,可以直接用它来约束对象的属性名必须符合某个Schema(比如枚举);
  • 而Draft 6及更早的规范没有这个关键字,只能用patternProperties间接实现,如果你用了新版本的写法但库只支持旧版本,就会出现校验不生效的情况。

正确的复用实现方式

1. 定义共享枚举片段

用$defs(Draft 7+)存储共享枚举,若需兼容旧版库则替换为definitions:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$defs": {
    "allowedKeys": {
      "enum": ["foo", "bar", "baz"]
    }
  }
}

2. 同时约束字符串属性与对象属性名

  • 字符串属性:直接通过$ref引用枚举即可
  • 对象属性名:使用propertyNames关键字绑定枚举,确保对象所有键名都在枚举列表内

完整Schema示例:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$defs": {
    "allowedKeys": {
      "enum": ["foo", "bar", "baz"]
    }
  },
  "type": "object",
  "properties": {
    "status": {
      "$ref": "#/$defs/allowedKeys"
    },
    "metadata": {
      "type": "object",
      "propertyNames": {
        "$ref": "#/$defs/allowedKeys"
      },
      "additionalProperties": true
    }
  }
}

3. 测试用JSON数据

{
  "status": "foo",
  "metadata": {
    "bar": "任意值都可以",
    "baz": 12345
  }
}

这份数据在支持Draft 7+的校验库(如Ajv v8及以上)中会被判定为有效,完全符合预期。

旧版本库的兼容方案

如果必须兼容Draft 6及更早的库,由于没有propertyNames关键字,只能用patternProperties配合正则间接约束属性名,但这种方式无法完全实现单一源维护,需同步更新枚举与正则:

{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "definitions": {
    "allowedKeys": {
      "enum": ["foo", "bar", "baz"]
    }
  },
  "type": "object",
  "properties": {
    "status": {
      "$ref": "#/definitions/allowedKeys"
    },
    "metadata": {
      "type": "object",
      "patternProperties": {
        "^(foo|bar|baz)$": { "type": "any" }
      },
      "additionalProperties": false
    }
  }
}

避坑要点

  • 明确指定Schema的$schema版本:不要让库自动推断,避免不同库用不同版本解析
  • 确认校验库支持的版本:比如Ajv v8默认使用Draft 2020-12,旧版Ajv可能默认用Draft 7,提前查阅官方文档
  • 优先使用新版本规范:$defs比definitions更清晰,propertyNames比patternProperties更直观,也能真正实现单一源维护

内容的提问来源于stack exchange,提问作者Mark_Sagecy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 02:15:38