如何使用JSON Schema的#defs复用重复键定义简化Schema编写
完全可以通过$defs统一定义公共键与值的约束规则,大幅简化JSON Schema编写,哪怕后续扩展到上百个同结构属性节点,也不需要重复编写学生姓名相关的键校验逻辑,维护成本极低。
实现思路
- 把所有属性节点共用的合法学生姓名列表,抽离到
$defs节点下作为公共枚举值,后续学生名单变动只需要修改这一处 - 在
$defs下定义通用的「学生属性映射对象」基础规则:要求这类对象的键必须来自前面的公共学生名枚举,可按需配置是否允许名单外的额外键、是否要求所有学生的键都必填 - 每个业务属性(比如
student_id/project/summer_camp)只需要引用这个通用基础对象规则,再单独声明自身对应的值类型、枚举范围即可,不需要重复编写键的约束 - 顶层的
Data数组单独做约束,限制数组元素只能是已定义的业务属性名即可
完整Schema示例
{ "type": "object", "$defs": { "studentNameEnum": { "enum": ["Alice", "Bob", "Charlie", "Derek", "Emily", "Florence"] }, "baseStudentMap": { "type": "object", "propertyNames": { "$ref": "#/$defs/studentNameEnum" }, "required": ["Alice", "Bob", "Charlie", "Derek", "Emily", "Florence"], "additionalProperties": false } }, "properties": { "student_id": { "$ref": "#/$defs/baseStudentMap", "additionalProperties": { "type": "integer", "minimum": 0 } }, "project": { "$ref": "#/$defs/baseStudentMap", "additionalProperties": { "enum": ["Science", "Math"] } }, "summer_camp": { "$ref": "#/$defs/baseStudentMap", "additionalProperties": { "type": "boolean" } }, "Data": { "type": "array", "items": { "enum": ["student_id", "project", "summer_camp"] }, "uniqueItems": true } }, "required": ["student_id", "project", "summer_camp", "Data"], "additionalProperties": false }
适配说明
- 如果你使用的是draft-7及更早版本的JSON Schema规范,只需要把代码里的
$defs替换为definitions即可,引用逻辑完全一致。 - 如果不需要强制要求每个学生在所有属性节点中都出现,直接删掉
baseStudentMap里的required字段即可。 - 后续新增同类型的学生属性,只需要在
properties中新增对应字段,引用#/$defs/baseStudentMap后单独定义值的约束规则即可,完全不需要重复编写学生名相关的键校验逻辑。 - 如果需要调整学生名单,仅需修改
$defs.studentNameEnum中的枚举值,所有引用该定义的属性会自动同步校验规则。
内容的提问来源于stack exchange,提问作者Veera S
相关产品推荐
相关产品推荐

