writing-json-schemas
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWriting JSON Schemas for z-schema
为z-schema编写JSON Schema
Write correct, idiomatic JSON Schemas validated by z-schema. Default target: draft-2020-12.
编写可通过z-schema验证的正确、符合规范的JSON Schema。默认目标版本:draft-2020-12。
Schema template
Schema模板
Start every schema with a declaration and :
$schematypejson
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
}Set explicitly when extra properties should be rejected — z-schema allows them by default.
additionalProperties: false每个schema都以声明和开头:
$schematypejson
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
}当需要拒绝额外属性时,请显式设置 —— z-schema默认允许额外属性。
additionalProperties: falseObject schemas
对象Schema
Basic object with required fields
带必填字段的基础对象
json
{
"type": "object",
"properties": {
"name": { "type": "string", "minLength": 1 },
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 0, "maximum": 150 }
},
"required": ["name", "email"],
"additionalProperties": false
}json
{
"type": "object",
"properties": {
"name": { "type": "string", "minLength": 1 },
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 0, "maximum": 150 }
},
"required": ["name", "email"],
"additionalProperties": false
}Nested objects
嵌套对象
json
{
"type": "object",
"properties": {
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"zip": { "type": "string", "pattern": "^\\d{5}(-\\d{4})?$" }
},
"required": ["street", "city"]
}
}
}json
{
"type": "object",
"properties": {
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"zip": { "type": "string", "pattern": "^\\\\d{5}(-\\\\d{4})?$" }
},
"required": ["street", "city"]
}
}
}Dynamic property names
动态属性名
Use to validate property keys by regex:
patternPropertiesjson
{
"type": "object",
"patternProperties": {
"^x-": { "type": "string" }
},
"additionalProperties": false
}Use (draft-06+) to constrain all property key strings:
propertyNamesjson
{
"type": "object",
"propertyNames": { "pattern": "^[a-z_]+$" }
}使用通过正则验证属性键:
patternPropertiesjson
{
"type": "object",
"patternProperties": {
"^x-": { "type": "string" }
},
"additionalProperties": false
}使用(draft-06及以上版本)约束所有属性键字符串:
propertyNamesjson
{
"type": "object",
"propertyNames": { "pattern": "^[a-z_]+$" }
}Array schemas
数组Schema
Uniform array
统一类型数组
json
{
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"uniqueItems": true
}json
{
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"uniqueItems": true
}Tuple validation (draft-2020-12)
元组验证(draft-2020-12)
Use for positional types, for remaining elements:
prefixItemsitemsjson
{
"type": "array",
"prefixItems": [{ "type": "string" }, { "type": "integer" }],
"items": false
}items: false使用定义位置类型,定义剩余元素的规则:
prefixItemsitemsjson
{
"type": "array",
"prefixItems": [{ "type": "string" }, { "type": "integer" }],
"items": false
}items: falseContains (draft-06+)
Contains(draft-06及以上版本)
Require at least one matching item:
json
{
"type": "array",
"contains": { "type": "string", "const": "admin" }
}With count constraints (draft-2019-09+):
json
{
"type": "array",
"contains": { "type": "integer", "minimum": 10 },
"minContains": 2,
"maxContains": 5
}要求至少有一个匹配的元素:
json
{
"type": "array",
"contains": { "type": "string", "const": "admin" }
}带计数约束(draft-2019-09及以上版本):
json
{
"type": "array",
"contains": { "type": "integer", "minimum": 10 },
"minContains": 2,
"maxContains": 5
}String constraints
字符串约束
json
{
"type": "string",
"minLength": 1,
"maxLength": 255,
"pattern": "^[A-Za-z0-9_]+$"
}json
{
"type": "string",
"minLength": 1,
"maxLength": 255,
"pattern": "^[A-Za-z0-9_]+$"
}Format validation
格式验证
z-schema has built-in format validators: , , , , , , , , , , , , , , , , , , .
datedate-timetimeemailidn-emailhostnameidn-hostnameipv4ipv6uriuri-referenceuri-templateiriiri-referencejson-pointerrelative-json-pointerregexdurationuuidjson
{ "type": "string", "format": "date-time" }Format assertions are always enforced by default (). For vocabulary-aware behavior in draft-2020-12, set on the validator.
formatAssertions: nullformatAssertions: truez-schema内置了格式验证器:、、、、、、、、、、、、、、、、、、。
datedate-timetimeemailidn-emailhostnameidn-hostnameipv4ipv6uriuri-referenceuri-templateiriiri-referencejson-pointerrelative-json-pointerregexdurationuuidjson
{ "type": "string", "format": "date-time" }格式断言默认始终强制执行()。如果要使用draft-2020-12的词汇感知行为,请在验证器上设置。
formatAssertions: nullformatAssertions: trueNumeric constraints
数值约束
json
{
"type": "number",
"minimum": 0,
"maximum": 100,
"multipleOf": 0.01
}Use / for strict bounds:
exclusiveMinimumexclusiveMaximumjson
{ "type": "integer", "exclusiveMinimum": 0, "exclusiveMaximum": 100 }json
{
"type": "number",
"minimum": 0,
"maximum": 100,
"multipleOf": 0.01
}使用/设置严格边界:
exclusiveMinimumexclusiveMaximumjson
{ "type": "integer", "exclusiveMinimum": 0, "exclusiveMaximum": 100 }Combinators
组合器
anyOf
— match at least one
anyOfanyOf
—— 至少匹配一个
anyOfjson
{
"anyOf": [{ "type": "string" }, { "type": "number" }]
}json
{
"anyOf": [{ "type": "string" }, { "type": "number" }]
}oneOf
— match exactly one
oneOfoneOf
—— 恰好匹配一个
oneOfjson
{
"oneOf": [
{ "type": "string", "maxLength": 5 },
{ "type": "string", "minLength": 10 }
]
}json
{
"oneOf": [
{ "type": "string", "maxLength": 5 },
{ "type": "string", "minLength": 10 }
]
}allOf
— match all
allOfallOf
—— 匹配所有
allOfUse for schema composition. Combine base schemas with refinements:
json
{
"allOf": [{ "$ref": "#/$defs/base" }, { "properties": { "extra": { "type": "string" } } }]
}用于schema组合,将基础schema和细化规则结合:
json
{
"allOf": [{ "$ref": "#/$defs/base" }, { "properties": { "extra": { "type": "string" } } }]
}not
— must not match
notnot
—— 必须不匹配
notjson
{ "not": { "type": "null" } }json
{ "not": { "type": "null" } }if
/ then
/ else
(draft-07+)
ifthenelseif
/then
/else
(draft-07及以上版本)
ifthenelseConditional validation — prefer over complex when the logic is "if X then require Y":
oneOfjson
{
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["personal", "business"] },
"company": { "type": "string" }
},
"if": { "properties": { "type": { "const": "business" } } },
"then": { "required": ["company"] },
"else": {}
}条件验证 —— 当逻辑为“如果X则要求Y”时,优先使用而非复杂的:
oneOfjson
{
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["personal", "business"] },
"company": { "type": "string" }
},
"if": { "properties": { "type": { "const": "business" } } },
"then": { "required": ["company"] },
"else": {}
}When to use which combinator
组合器选型参考
| Scenario | Use |
|---|---|
| Value can be multiple types | |
| Exactly one variant must match | |
| Compose inherited schemas | |
| "if condition then require fields" | |
| Exclude a specific shape | |
Prefer // over when the condition is a single discriminator field — it produces clearer error messages.
ifthenelseoneOf| 场景 | 使用组合器 |
|---|---|
| 值可以为多种类型 | |
| 必须恰好匹配一个变体 | |
| 组合继承的schema | |
| "如果满足条件则要求某些字段" | |
| 排除特定结构 | |
当条件是单个判别字段时,优先使用//而非 —— 它会生成更清晰的错误信息。
ifthenelseoneOfSchema reuse with $ref
and $defs
$ref$defs使用$ref
和$defs
复用Schema
$ref$defsLocal definitions
本地定义
json
{
"$defs": {
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" }
},
"required": ["street", "city"]
}
},
"type": "object",
"properties": {
"home": { "$ref": "#/$defs/address" },
"work": { "$ref": "#/$defs/address" }
}
}json
{
"$defs": {
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" }
},
"required": ["street", "city"]
}
},
"type": "object",
"properties": {
"home": { "$ref": "#/$defs/address" },
"work": { "$ref": "#/$defs/address" }
}
}Cross-schema references
跨Schema引用
Compile an array of schemas and reference by ID:
typescript
import ZSchema from 'z-schema';
const schemas = [
{
$id: 'address',
type: 'object',
properties: { city: { type: 'string' } },
required: ['city'],
},
{
$id: 'person',
type: 'object',
properties: {
name: { type: 'string' },
home: { $ref: 'address' },
},
required: ['name'],
},
];
const validator = ZSchema.create();
validator.validateSchema(schemas);
validator.validate({ name: 'Alice', home: { city: 'Paris' } }, 'person');编译schema数组并通过ID引用:
typescript
import ZSchema from 'z-schema';
const schemas = [
{
$id: 'address',
type: 'object',
properties: { city: { type: 'string' } },
required: ['city'],
},
{
$id: 'person',
type: 'object',
properties: {
name: { type: 'string' },
home: { $ref: 'address' },
},
required: ['name'],
},
];
const validator = ZSchema.create();
validator.validateSchema(schemas);
validator.validate({ name: 'Alice', home: { city: 'Paris' } }, 'person');Strict schemas with unevaluatedProperties
(draft-2019-09+)
unevaluatedProperties使用unevaluatedProperties
编写严格Schema(draft-2019-09及以上版本)
unevaluatedPropertiesWhen combining schemas with , in a sub-schema blocks properties defined in sibling schemas. Use instead — it tracks all properties evaluated across applicators:
allOfadditionalProperties: falseunevaluatedPropertiesjson
{
"allOf": [
{
"type": "object",
"properties": { "name": { "type": "string" } },
"required": ["name"]
},
{
"type": "object",
"properties": { "age": { "type": "integer" } }
}
],
"unevaluatedProperties": false
}This accepts but rejects .
{ "name": "Alice", "age": 30 }{ "name": "Alice", "age": 30, "extra": true }当使用组合schema时,子schema中的会阻止同级schema中定义的属性生效。请改用 —— 它会跟踪所有应用器中评估过的属性:
allOfadditionalProperties: falseunevaluatedPropertiesjson
{
"allOf": [
{
"type": "object",
"properties": { "name": { "type": "string" } },
"required": ["name"]
},
{
"type": "object",
"properties": { "age": { "type": "integer" } }
}
],
"unevaluatedProperties": false
}上述配置会接受,但会拒绝。
{ "name": "Alice", "age": 30 }{ "name": "Alice", "age": 30, "extra": true }Validating the schema itself
验证Schema本身
Always validate schemas at startup:
typescript
const validator = ZSchema.create();
try {
validator.validateSchema(schema);
} catch (err) {
console.log('Schema errors:', err.details);
}请始终在启动时验证schema:
typescript
const validator = ZSchema.create();
try {
validator.validateSchema(schema);
} catch (err) {
console.log('Schema errors:', err.details);
}Common mistakes
常见错误
- Forgetting : By default, extra properties are allowed. Set
additionalPropertiesor useadditionalProperties: falseto reject them.unevaluatedProperties: false - Using with
additionalProperties: false: This blocks properties from sibling schemas. UseallOfat the top level instead (draft-2019-09+).unevaluatedProperties: false - Array in draft-2020-12: Use
itemsfor tuple validation.prefixItemsnow means "schema for remaining items".items - Missing : Without it, z-schema uses its configured default draft. Include
$schemafor explicit draft targeting.$schema - vs
definitions: Both work, but$defsis the canonical form in draft-2019-09+. Use it consistently.$defs
- 忘记设置:默认情况下允许额外属性。设置
additionalProperties或使用additionalProperties: false来拒绝额外属性。unevaluatedProperties: false - 在中使用
allOf:这会阻止同级schema中的属性生效。请在顶层使用additionalProperties: false替代(draft-2019-09及以上版本)。unevaluatedProperties: false - draft-2020-12中的数组:元组验证请使用
items。现在prefixItems的含义是“剩余元素的schema”。items - 缺少:没有该声明时,z-schema会使用其配置的默认草案版本。请添加
$schema显式指定目标版本。$schema - 和
definitions的区别:两者都可用,但$defs是draft-2019-09及以上版本的规范写法,请统一使用。",$defs