关于 migrating-json-schemas
面向开发者的 JSON Schema 草案迁移指南,使用 z-schema 检查兼容性。它结合关键字映射、迁移步骤,以及对模式和数据的验证。
主要功能
- 01Draft-04 至 2020-12 迁移指南
- 02跨草案关键字映射
- 03使用 z-schema 验证模式
- 04迁移后检查数据
适用场景
- 01将旧模式升级到 draft-2020-12
- 02查找不兼容的模式关键字
- 03检查迁移后的模式和样例数据
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ zaggino/ z-schema --skill migrating-json-schemas安装后在 Claude Code 中输入/migrating-json-schemas确认已加载。
附带文件references/keyword-mapping.md
详细介绍
在不同草案版本间迁移 JSON Schema
z-schema 支持 draft-04、draft-06、draft-07、draft-2019-09 和 draft-2020-12。本指南介绍如何在不同草案版本间迁移 Schema,并使用 z-schema 验证。
迁移工作流
- 确定源草案版本(检查
$schema或id/$id的用法)。 - 在验证器上设置目标版本:
import ZSchema from 'z-schema'; const validator = ZSchema.create({ version: 'draft2020-12' }); - 运行
validator.validateSchema(schema),检查是否存在不兼容项。 - 使用下方的关键字映射修复每个报告的错误。
- 重新验证,直到 Schema 通过。
快速参考:关键字变更
| 旧关键字(draft-04) | 新关键字(draft-2020-12) | 引入版本 |
|---|---|---|
id | $id | draft-06 |
definitions | $defs | draft-2019-09 |
数组形式的 items(元组) | prefixItems | draft-2020-12 |
additionalItems | items(存在 prefixItems 时) | draft-2020-12 |
exclusiveMinimum: true(布尔值) | exclusiveMinimum: <number> | draft-06 |
exclusiveMaximum: true(布尔值) | exclusiveMaximum: <number> | draft-06 |
dependencies(字符串数组) | dependentRequired | draft-2019-09 |
dependencies(Schema 值) | dependentSchemas | draft-2019-09 |
$recursiveRef / $recursiveAnchor | $dynamicRef / $dynamicAnchor | draft-2020-12 |
如需查看包含示例的完整关键字映射,请参阅 references/keyword-mapping.md。
常见迁移路径
Draft-04 → Draft-2020-12
这是跨度最大的一次迁移。请按顺序应用以下更改:
1. 将 id 重命名为 $id
// Before (draft-04)
{ "id": "http://example.com/person.json", "type": "object" }
// After (draft-2020-12)
{ "$id": "http://example.com/person.json", "type": "object" }
2. 将布尔值 exclusiveMinimum/exclusiveMaximum 转换为数字
// Before (draft-04)
{ "type": "number", "minimum": 0, "exclusiveMinimum": true }
// After (draft-2020-12)
{ "type": "number", "exclusiveMinimum": 0 }
注意:将 minimum 关键字转换为数值 exclusiveMinimum 时应移除它,因为 exclusiveMinimum: 0 表示“大于 0”。
3. 将 definitions 重命名为 $defs
// Before
{ "definitions": { "address": { "type": "object" } } }
// After
{ "$defs": { "address": { "type": "object" } } }
将所有指向 #/definitions/... 的 $ref 值更新为 #/$defs/...。
4. 拆分 dependencies
// Before (draft-04) — mixed dependencies
{
"dependencies": {
"billing_address": ["credit_card"],
"credit_card": { "type": "object", "properties": { "cvv": { "type": "string" } } }
}
}
// After (draft-2020-12) — split into two keywords
{
"dependentRequired": {
"billing_address": ["credit_card"]
},
"dependentSchemas": {
"credit_card": { "type": "object", "properties": { "cvv": { "type": "string" } } }
}
}
5. 将元组形式的 items 转换为 prefixItems
// Before (draft-04)
{
"type": "array",
"items": [{ "type": "string" }, { "type": "number" }],
"additionalItems": false
}
// After (draft-2020-12)
{
"type": "array",
"prefixItems": [{ "type": "string" }, { "type": "number" }],
"items": false
}
当 items 是数组(元组验证)时,应将其改为 prefixItems。旧的 additionalItems 应改为 items。
6. 添加 $schema 声明
{ "$schema": "https://json-schema.org/draft/2020-12/schema" }
Draft-07 → Draft-2020-12
跨度较小。主要变更:
definitions→$defs(并更新$ref路径)- 数组形式的
items→prefixItems additionalItems→items(存在prefixItems时)dependencies→dependentRequired/dependentSchemas- 考虑采用
unevaluatedProperties/unevaluatedItems,以便对组合 Schema 进行更严格的验证
Draft-2019-09 → Draft-2020-12
仅需少量更改:
- 数组形式的
items→prefixItems,additionalItems→items $recursiveRef/$recursiveAnchor→$dynamicRef/$dynamicAnchor
验证迁移后的 Schema
迁移完成后,使用目标草案版本的元 Schema 验证 Schema 本身:
import ZSchema from 'z-schema';
const validator = ZSchema.create({ version: 'draft2020-12' });
try {
validator.validateSchema(migratedSchema);
console.log('Schema is valid for draft-2020-12');
} catch (err) {
console.log('Schema issues:', err.details);
}
然后测试数据验证,确认行为没有改变:
// Test with known-good data
validator.validate(knownGoodData, migratedSchema);
// Test with known-bad data
const { valid } = validator.validateSafe(knownBadData, migratedSchema);
if (valid) {
console.warn('Migration issue: previously invalid data now passes');
}
向后兼容性
如果 Schema 必须兼容多个草案版本,请使用 version: 'none',并在每个 Schema 中设置 $schema 以声明其草案版本:
const validator = ZSchema.create({ version: 'none' });
参考文件
- references/keyword-mapping.md — 所有草案版本的完整关键字映射,包含变更前后的示例