migrating-json-schemas
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMigrating JSON Schemas Between Drafts
JSON Schema草案版本迁移
z-schema supports draft-04, draft-06, draft-07, draft-2019-09, and draft-2020-12. This skill covers migrating schemas between drafts and verifying them with z-schema.
z-schema支持draft-04、draft-06、draft-07、draft-2019-09和draft-2020-12。本技能覆盖不同草案版本间的schema迁移,以及如何使用z-schema对其进行验证。
Migration workflow
迁移工作流
- Identify the source draft (check or
$schema/idusage).$id - Set the target version on the validator:
typescript
import ZSchema from 'z-schema'; const validator = ZSchema.create({ version: 'draft2020-12' }); - Run to surface incompatibilities.
validator.validateSchema(schema) - Fix each reported error using the keyword mapping below.
- Re-validate until the schema passes.
- 确定源草案版本(检查或
$schema/id的使用情况)。$id - 在验证器上设置目标版本:
typescript
import ZSchema from 'z-schema'; const validator = ZSchema.create({ version: 'draft2020-12' }); - 运行来排查不兼容问题。
validator.validateSchema(schema) - 使用下方的关键字映射修复每个上报的错误。
- 重新验证直到schema通过校验。
Quick reference: keyword changes
快速参考:关键字变更
| Old keyword (draft-04) | New keyword (draft-2020-12) | Introduced in |
|---|---|---|
| | draft-06 |
| | draft-2019-09 |
Array-form | | draft-2020-12 |
| | draft-2020-12 |
| | draft-06 |
| | draft-06 |
| | draft-2019-09 |
| | draft-2019-09 |
| | draft-2020-12 |
For the complete keyword mapping with examples, see references/keyword-mapping.md.
| 旧关键字(draft-04) | 新关键字(draft-2020-12) | 引入版本 |
|---|---|---|
| | draft-06 |
| | draft-2019-09 |
数组形式 | | draft-2020-12 |
| | draft-2020-12 |
| | draft-06 |
| | draft-06 |
| | draft-2019-09 |
| | draft-2019-09 |
| | draft-2020-12 |
完整带示例的关键字映射请查看 references/keyword-mapping.md。
Common migration paths
常见迁移路径
Draft-04 → Draft-2020-12
Draft-04 → Draft-2020-12
This is the largest jump. Apply changes in order:
1. Rename to
id$idjson
// Before (draft-04)
{ "id": "http://example.com/person.json", "type": "object" }
// After (draft-2020-12)
{ "$id": "http://example.com/person.json", "type": "object" }2. Convert boolean / to numeric
exclusiveMinimumexclusiveMaximumjson
// Before (draft-04)
{ "type": "number", "minimum": 0, "exclusiveMinimum": true }
// After (draft-2020-12)
{ "type": "number", "exclusiveMinimum": 0 }Note: the keyword is removed when converting to as a number, since means "greater than 0".
minimumexclusiveMinimumexclusiveMinimum: 03. Rename to
definitions$defsjson
// Before
{ "definitions": { "address": { "type": "object" } } }
// After
{ "$defs": { "address": { "type": "object" } } }Update all values that point to → .
$ref#/definitions/...#/$defs/...4. Split
dependenciesjson
// 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. Convert tuple to
itemsprefixItemsjson
// 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
}When was an array (tuple validation), it becomes . The old becomes .
itemsprefixItemsadditionalItemsitems6. Add declaration
$schemajson
{ "$schema": "https://json-schema.org/draft/2020-12/schema" }这是跨度最大的版本升级,请按顺序应用变更:
1. 将重命名为
id$idjson
// Before (draft-04)
{ "id": "http://example.com/person.json", "type": "object" }
// After (draft-2020-12)
{ "$id": "http://example.com/person.json", "type": "object" }2. 将布尔型的/转换为数值型
exclusiveMinimumexclusiveMaximumjson
// Before (draft-04)
{ "type": "number", "minimum": 0, "exclusiveMinimum": true }
// After (draft-2020-12)
{ "type": "number", "exclusiveMinimum": 0 }注意:转换为数值型时会移除关键字,因为表示“大于0”。
exclusiveMinimumminimumexclusiveMinimum: 03. 将重命名为
definitions$defsjson
// Before
{ "definitions": { "address": { "type": "object" } } }
// After
{ "$defs": { "address": { "type": "object" } } }将所有指向的值更新为。
#/definitions/...$ref#/$defs/...4. 拆分
dependenciesjson
// Before (draft-04) — 混合依赖
{
"dependencies": {
"billing_address": ["credit_card"],
"credit_card": { "type": "object", "properties": { "cvv": { "type": "string" } } }
}
}
// After (draft-2020-12) — 拆分为两个关键字
{
"dependentRequired": {
"billing_address": ["credit_card"]
},
"dependentSchemas": {
"credit_card": { "type": "object", "properties": { "cvv": { "type": "string" } } }
}
}5. 将元组形式的转换为
itemsprefixItemsjson
// 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
}当为数组(元组校验)时,它会变为,旧的则变为。
itemsprefixItemsadditionalItemsitems6. 添加声明
$schemajson
{ "$schema": "https://json-schema.org/draft/2020-12/schema" }Draft-07 → Draft-2020-12
Draft-07 → Draft-2020-12
Smaller jump. Main changes:
- →
definitions(and update$defspaths)$ref - Array-form →
itemsprefixItems - →
additionalItems(whenitemspresent)prefixItems - →
dependencies/dependentRequireddependentSchemas - Consider adopting /
unevaluatedPropertiesfor stricter validation of combined schemasunevaluatedItems
跨度较小,主要变更:
- →
definitions(同时更新$defs路径)$ref - 数组形式的→
itemsprefixItems - →
additionalItems(当存在items时)prefixItems - →
dependencies/dependentRequireddependentSchemas - 考虑采用/
unevaluatedProperties对组合schema进行更严格的校验unevaluatedItems
Draft-2019-09 → Draft-2020-12
Draft-2019-09 → Draft-2020-12
Minimal changes:
- Array-form →
items,prefixItems→additionalItemsitems - /
$recursiveRef→$recursiveAnchor/$dynamicRef$dynamicAnchor
变更最少:
- 数组形式的→
items,prefixItems→additionalItemsitems - /
$recursiveRef→$recursiveAnchor/$dynamicRef$dynamicAnchor
Verifying a migrated schema
验证已迁移的schema
After migration, validate the schema itself against the target draft's meta-schema:
typescript
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);
}Then test data validation to confirm behavior is unchanged:
typescript
// 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验证schema本身:
typescript
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);
}然后测试数据校验,确认行为没有发生变化:
typescript
// 使用已知合法数据测试
validator.validate(knownGoodData, migratedSchema);
// 使用已知非法数据测试
const { valid } = validator.validateSafe(knownBadData, migratedSchema);
if (valid) {
console.warn('迁移问题:此前非法的数据现在通过了校验');
}Backward compatibility
向后兼容性
If schemas must work across multiple draft versions, use and set in each schema to declare its own draft:
version: 'none'$schematypescript
const validator = ZSchema.create({ version: 'none' });如果schema需要跨多个草案版本使用,请设置,并在每个schema中设置来声明自身的草案版本:
version: 'none'$schematypescript
const validator = ZSchema.create({ version: 'none' });Reference files
参考文件
- references/keyword-mapping.md — Complete keyword mapping across all drafts with before/after examples
- references/keyword-mapping.md — 覆盖所有草案版本的完整关键字映射,包含变更前后示例