为什么你需要 JSON Schema?
先说一个常见场景:你在写一个 REST API,前端传了一个 JSON 请求体。你的后端代码直接 req.body.user.name,然后报了 Cannot read property 'name' of undefined。
问题出在哪?前端传的 JSON 里根本没有 user 这个字段。
如果有一个 JSON Schema 定义了 user 必须存在、name 必须是字符串、age 必须是整数——前端在发请求前就能被拦截,后端也能少写一堆防御性代码。
JSON Schema 就是这个东西。它是描述 JSON 数据结构的标准格式,用来验证、生成、文档化你的 JSON 数据。
JSON Schema 基础语法
一个最简单的 JSON Schema 长这样:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "用户信息",
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer", "minimum": 0 },
"email": { "type": "string", "format": "email" }
},
"required": ["name", "email"]
}
几个关键字段解释一下:
- $schema:声明使用的 Draft 版本,推荐用 draft-07
- type:数据类型,可以是 object、array、string、number、integer、boolean、null
- properties:对象属性定义,key 是属性名,value 是这个属性的 Schema
- required:必填字段列表,不在这里的字段可选
比 string 类型多了很多约束选项:
{
"type": "string",
"minLength": 1,
"maxLength": 100,
"pattern": "^[a-zA-Z0-9_-]+$"
}
pattern 就是正则表达式,可以用来校验用户名、手机号、身份证号之类的。
常用验证场景
数组验证
{
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"maxItems": 10
}
上面这个 Schema 表示:必须是一个数组,元素全是字符串,长度 1 到 10。
嵌套对象
{
"type": "object",
"properties": {
"address": {
"type": "object",
"properties": {
"city": { "type": "string" },
"zipCode": { "type": "string", "pattern": "^\\d{6}$" }
},
"required": ["city", "zipCode"]
}
},
"required": ["address"]
}
嵌套对象就是把另一个完整 Schema 放在 properties 里。实际项目中 API 响应结构经常是三四层嵌套的。
条件校验
有时候某些字段只在特定条件下才需要:
{
"if": { "properties": { "paymentMethod": { "const": "card" } } },
"then": { "required": ["cardNumber", "expiryDate"] },
"else": { "required": ["accountNumber"] }
}
这是 draft-07 的 if/then/else 语法,非常实用。比如支付方式选了银行卡就要填卡号,选了支付宝就要填账号。
Python 实战验证
用 jsonschema 库,三行搞定:
import json
from jsonschema import validate, ValidationError
schema = {
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 1},
"age": {"type": "integer", "minimum": 0},
"email": {"type": "string", "format": "email"}
},
"required": ["name", "email"],
"additionalProperties": False
}
data = {"name": "张三", "email": "zhangsan@example.com", "age": 25}
try:
validate(instance=data, schema=schema)
print("✅ 验证通过")
except ValidationError as e:
print(f"❌ 验证失败: {e.message}")
additionalProperties: False 这个设置很关键。它会让 Schema 拒绝任何不在 properties 中定义的额外字段。很多 API 安全漏洞就是因为后端接受了前端多传的恶意字段。
安装命令:pip install jsonschema
Node.js 实战验证
Node.js 生态推荐用 ajv(Another JSON Schema Validator),性能比官方推荐的 json-schema-traverse 好很多:
const Ajv = require('ajv');
const ajv = new Ajv({ allErrors: true });
const schema = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
age: { type: 'integer', minimum: 0 },
email: { type: 'string', format: 'email' }
},
required: ['name', 'email'],
additionalProperties: false
};
const data = { name: '张三', email: 'zhangsan@example.com', age: 25 };
const validate = ajv.compile(schema);
if (validate(data)) {
console.log('✅ 验证通过');
} else {
console.log('❌ 验证失败:', validate.errors);
}
安装命令:npm install ajv
Ajv 支持 JSON Schema draft-07 的全部特性,包括 if/then/else、正则表达式、自定义格式校验器等。
从 Schema 生成代码
JSON Schema 不只是用来验证的,它还能反向生成代码。
TypeScript 类型生成
用 quicktype 可以从 JSON Schema 自动生成 TypeScript 接口:
npx quicktype schema.json -o types.ts -l ts --just-types
生成的文件长这样:
export interface User {
name: string;
email: string;
age?: number;
}
Python 模型生成
用 datamodel-code-generator:
pip install datamodel-code-generator
datamodel-codegen --input schema.json --input-file-type jsonschema --output models.py
会生成 Pydantic 模型,自带验证逻辑。前后端共用一个 Schema 文件,两边类型一致,不会再出现 “前端说发了 name 字段,后端说没收到” 的扯皮情况。
常见坑和避坑指南
坑1:format 校验默认不开启
Python 的 jsonschema 库和 Node.js 的 Ajv 不同。Ajv 默认不校验 format(比如 email、uri),需要手动添加插件:
const addFormats = require('ajv-formats');
addFormats(ajv);
坑2:integer vs number 搞混
JSON Schema 里 integer 和 number 是两个不同的类型。5 是 integer,5.0 也是 integer(因为值等于整数),但 5.5 就不是。别把整数校验写成 number 类型。
坑3:required 数组为空
"required": [] 表示所有字段都是可选的,不是"没有必填字段"。如果你不写 required 字段,那所有字段默认都是可选的。
坑4:Draft 版本不一致
不同版本的 JSON Schema 语法有差异。draft-04 用 required: true/false,draft-06 改成 required: ["field1"] 数组形式。确保你的验证库和 Schema 文件的 $schema 声明匹配。
总结
JSON Schema 的价值在于一处定义,处处生效。一个 Schema 文件可以同时用于:
- API 请求/响应的数据校验
- 前后端类型同步
- 自动生成文档(Swagger/OpenAPI 底层就用 JSON Schema)
- 测试用例的数据生成
把它纳入你的开发流程,能省掉大量边界情况的 bug 处理时间。
想快速验证你的 JSON 数据?试试我们站上的 JSON 格式化工具,支持 Schema 校验预览。