JSON Schema 是描述 JSON 数据结构、约束和验证规则的标准方式。无论你需要从 JSON 创建 Schema、验证 API 载荷,还是生成文档,JSON Schema 都提供了人类和机器都能理解的声明式词汇。本指南涵盖了从基础到高级特性,包括 $ref、条件模式,以及 Python 和 JavaScript 中的代码级验证。
试用我们免费的 JSON 转 JSON Schema 生成器。
什么是 JSON Schema?
JSON Schema 是一种基于 JSON 的词汇,允许你对 JSON 文档进行注解和验证。它定义了预期的数据类型、必填属性、值约束和结构模式。
JSON Schema 广泛用于 API 请求/响应验证(OpenAPI/Swagger)、配置文件验证、UI 框架中的表单生成、数据库文档验证(MongoDB)和基础设施即代码工具(Terraform、Kubernetes)。
JSON Schema 规范已经历多个草案版本。Draft-07 是支持最广泛的版本,Draft 2020-12 是最新的稳定版本。
JSON Schema 草案版本:该用哪个?
JSON Schema 经历了多个草案版本的发展:
| 草案 | 年份 | 新增关键特性 | 适用场景 |
|---|---|---|---|
| Draft-04 | 2013 | 核心词汇、$ref | 遗留系统 |
| Draft-06 | 2017 | const、contains | 中等兼容性 |
| Draft-07 | 2018 | if/then/else、readOnly | 大多数项目(最广泛支持) |
| 2019-09 | 2019 | $anchor、unevaluatedProperties | 高级模式 |
| 2020-12 | 2020 | $dynamicRef、prefixItems | 使用最新规范的新项目 |
对于大多数项目,Draft-07 提供了功能和库支持之间的最佳平衡。
如何从 JSON 创建 JSON Schema
从 JSON 创建 JSON Schema 包括分析 JSON 样本文档并生成描述其结构的模式:
- 识别顶层类型:确定根是对象、数组还是原始值。
- 定义属性:为 JSON 对象中的每个键创建属性定义。
- 设置必填字段:将属性名添加到
"required"数组。 - 添加约束:使用
minLength、pattern、enum等关键字。 - 处理嵌套对象:定义内联模式或使用
$ref引用共享定义。 - 处理数组:使用
"items"定义数组元素的模式。 - 添加元数据:包括
$schema、title、description。
// Example: Sample JSON input
{
"id": 1,
"name": "Alice Johnson",
"email": "alice@example.com",
"age": 28,
"is_active": true,
"roles": ["admin", "editor"],
"address": {
"street": "123 Main St",
"city": "Springfield",
"zip": "62704"
}
}
// Generated JSON Schema (Draft-07)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "User",
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" },
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 0 },
"is_active": { "type": "boolean" },
"roles": {
"type": "array",
"items": { "type": "string" }
},
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"zip": { "type": "string", "pattern": "^[0-9]{5}$" }
},
"required": ["street", "city", "zip"]
}
},
"required": ["id", "name", "email", "is_active"]
}JSON Schema 核心关键字
JSON Schema 使用丰富的关键字来描述数据:
| 类别 | 关键字 | 用途 |
|---|---|---|
| 类型 | type、enum、const | 定义允许的类型和值 |
| 字符串 | minLength、maxLength、pattern、format | 约束字符串值 |
| 数字 | minimum、maximum、multipleOf | 约束数值范围 |
| 对象 | properties、required、additionalProperties | 定义对象形状 |
| 数组 | items、minItems、uniqueItems | 定义数组约束 |
| 组合 | allOf、anyOf、oneOf、not | 组合多个模式 |
| 条件 | if、then、else | 条件验证 |
| 引用 | $ref、$defs | 复用模式组件 |
代码示例:使用 JSON Schema 验证 JSON
Python:jsonschema 库
jsonschema 是 Python 中最流行的 JSON Schema 验证库,支持 Draft-04 到 Draft 2020-12:
import json
from jsonschema import validate, ValidationError, Draft7Validator
# Define the schema
schema = {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 1},
"email": {"type": "string", "format": "email"},
"age": {"type": "integer", "minimum": 0, "maximum": 150},
"roles": {
"type": "array",
"items": {"type": "string", "enum": ["admin", "editor", "viewer"]},
"minItems": 1,
"uniqueItems": True
}
},
"required": ["name", "email"],
"additionalProperties": False
}
# Valid data
valid_data = {
"name": "Alice",
"email": "alice@example.com",
"age": 28,
"roles": ["admin", "editor"]
}
# Validate
try:
validate(instance=valid_data, schema=schema)
print("Validation passed!")
except ValidationError as e:
print(f"Validation failed: {e.message}")
# Collect all errors at once
invalid_data = {"name": "", "email": "not-an-email", "age": -5}
validator = Draft7Validator(schema)
errors = list(validator.iter_errors(invalid_data))
for error in errors:
print(f"Error at {list(error.path)}: {error.message}")JavaScript/Node.js:Ajv
Ajv 是 JavaScript 生态中最快和最广泛使用的 JSON Schema 验证器:
import Ajv from "ajv";
import addFormats from "ajv-formats";
const ajv = new Ajv({ allErrors: true });
addFormats(ajv); // Adds "email", "uri", "date-time", etc.
const schema = {
type: "object",
properties: {
name: { type: "string", minLength: 1 },
email: { type: "string", format: "email" },
age: { type: "integer", minimum: 0 },
tags: {
type: "array",
items: { type: "string" },
uniqueItems: true
},
address: {
type: "object",
properties: {
street: { type: "string" },
city: { type: "string" },
country: { type: "string", default: "US" }
},
required: ["street", "city"]
}
},
required: ["name", "email"],
additionalProperties: false,
};
// Compile schema once, validate many times (fast!)
const validate = ajv.compile(schema);
const data = {
name: "Bob",
email: "bob@example.com",
age: 35,
tags: ["developer", "writer"],
address: { street: "456 Oak Ave", city: "Portland" }
};
if (validate(data)) {
console.log("Valid!");
} else {
console.log("Errors:", validate.errors);
// Each error: { keyword, dataPath, message, params }
}使用 $ref 实现可复用的 Schema 组件
随着 Schema 的增长,你会发现重复的模式。$ref 关键字允许你引用在其他地方定义的模式,保持 DRY 原则。
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"billing_address": { "$ref": "#/definitions/Address" },
"shipping_address": { "$ref": "#/definitions/Address" },
"user": { "$ref": "#/definitions/User" }
},
"definitions": {
"Address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"state": { "type": "string", "minLength": 2, "maxLength": 2 },
"zip": { "type": "string", "pattern": "^[0-9]{5}(-[0-9]{4})?$" }
},
"required": ["street", "city", "state", "zip"]
},
"User": {
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string", "format": "email" }
},
"required": ["name", "email"]
}
}
}$ref 使用 JSON Pointer 语法引用定义。Draft-07 中定义存储在 "definitions" 下,Draft 2020-12 中标准位置是 "$defs"。
广泛使用 $ref 可以将你的模式从单体文档转变为模块化架构,在 OpenAPI 规范中尤其有价值。
必填字段和默认值
"required" 关键字是必须出现在有效 JSON 对象中的属性名数组。
"default" 关键字为未提供的属性指定默认值。注意规范不强制验证器填充默认值,具体行为取决于库的实现。
常见验证模式
以下是实际 API 开发中常见的 JSON Schema 验证模式:
邮箱验证:使用 "format": "email" 进行基本检查。
日期时间验证:使用 "format": "date-time" 验证 ISO 8601 时间戳。
枚举值:使用 "enum" 限制字段为固定值集合。
条件模式:使用 if/then/else 根据数据值应用不同的验证规则。
// Conditional schema: if/then/else (Draft-07+)
{
"type": "object",
"properties": {
"account_type": { "enum": ["personal", "business"] },
"name": { "type": "string" }
},
"required": ["account_type", "name"],
"if": {
"properties": { "account_type": { "const": "business" } }
},
"then": {
"properties": {
"company_name": { "type": "string", "minLength": 1 },
"tax_id": { "type": "string", "pattern": "^[0-9]{2}-[0-9]{7}$" }
},
"required": ["company_name", "tax_id"]
},
"else": {
"properties": {
"date_of_birth": { "type": "string", "format": "date" }
}
}
}JSON Schema 最佳实践
从 Draft-07 开始:拥有最广泛的库支持,包含条件验证。
谨慎使用 additionalProperties: false:它会拒绝未列出的属性,但会破坏 allOf 组合。
使用 $ref 和 $defs 组织:提取共享模式为可复用定义。
添加 title 和 description:生成人类可读的文档并改善 IDE 自动补全。
使用 format 关键字:"format": "uri"、"format": "email" 传达语义意图。
使用多个验证器测试:不同库对边界情况的解释不同。
版本化 Schema:使用 $id 和版本号 URL 支持模式演进。
相关工具:JSON 格式化器、JSON 验证器、JSON 转 TypeScript。
JSON to JSON SchemaJSON FormatterJSON ValidatorJSON to TypeScript
常见问题
如何从现有 JSON 文件生成 JSON Schema?
使用我们的免费在线 JSON 转 JSON Schema 工具:粘贴 JSON,即时生成包含推断类型和必填字段的 Draft-07 模式。编程方式可使用 Python 的 genson 或 Node.js 的 json-schema-generator。
JSON Schema Draft-07 和 Draft 2020-12 有什么区别?
Draft 2020-12 引入了 $dynamicRef、prefixItems 替代数组形式的 items、$vocabulary 以及默认将 format 视为注解。Draft-07 有更广泛的库支持,满足大多数使用场景。
JSON Schema 能验证嵌套对象和数组吗?
可以。使用 properties 和内联对象模式处理嵌套对象,使用 items 和对象模式处理对象数组。可以任意深度嵌套,使用 $ref 引用共享结构避免重复。
如何使 JSON Schema 字段可选?
从 required 数组中省略字段名即可。在 properties 中定义但不在 required 中列出的属性是可选的。
Python 和 JavaScript 最好的 JSON Schema 验证器是什么?
Python 推荐 jsonschema(支持所有草案),JavaScript 推荐 Ajv(最快且功能最完整),两者都在积极维护。
JSON Schema 是验证、文档化和强制执行 JSON 数据合约的必备工具。使用我们的免费在线工具即时生成 JSON Schema,并参考本指南了解最佳实践。
使用我们的免费在线工具即时从 JSON 生成 JSON Schema。
Related Developer Tools and Guides
- JSON to JSON Schema Generator - Generate JSON Schema from any JSON data
- JSON Formatter - Format and beautify JSON data
- JSON Validator - Validate JSON syntax and structure
- JSON to TypeScript Converter - Generate TypeScript interfaces from JSON
- JSON to Go Converter - Create Go structs from JSON
- JSON to Java Converter - Generate Java classes from JSON
- JSON to Kotlin Converter - Create Kotlin data classes from JSON
- JSON to Python Converter - Generate Python dataclasses from JSON
- JSON to YAML Converter - Convert between JSON and YAML formats
- JSON vs YAML vs TOML - Comparison of configuration formats