JSON Schema 是什么?用法、示例与完整教程(2026)
处理 API 响应或配置文件时,JSON 语法正确并不代表数据「合法」——字段缺失、类型错误或取值越界,往往要到运行时才会暴露。JSON Schema 正是为解决这类问题而诞生的规范。本文将从定义与使用场景出发,逐步讲解基本写法、常用关键字、实战校验流程与工具选型,帮助你建立一套可落地的 JSON 数据约束方案。
阅读前速览
| 项目 | 说明 |
|---|---|
| 核心问题 | JSON 语法正确,但结构或取值不符合业务约定 |
| 解决思路 | 用 Schema 声明字段类型、必填项与约束,再自动校验 |
| 推荐版本 | Draft 2020-12(生态支持最成熟) |
| 本文覆盖 | 定义 → 写法 → 关键字 → 实战 → 选型 → FAQ |
JSON Schema 是什么?
JSON Schema 是一种基于 JSON 的规范,用来描述「一份 JSON 数据应该满足什么条件」。你可以把它理解为数据的类型声明 + 约束规则:哪些字段必须存在、每个字段是什么类型、字符串长度或数值范围是多少、数组元素应满足什么结构,都可以写进 Schema 里。
它本身也是合法的 JSON 文档,只是语义不同——Schema 不承载业务数据,而是描述业务数据的形状。OpenAPI 3.x 用 JSON Schema 描述请求/响应体;很多 CLI 工具用 Schema 校验配置文件;前端表单库也常用 Schema 驱动校验逻辑。掌握它之后,你可以在前端、后端、CI 流水线里复用同一份约束定义,减少「各端各写一套校验」的重复劳动。
为什么需要 JSON Schema?
日常开发里,JSON.parse() 只能告诉你括号是否配对、引号是否正确。以下情况语法校验完全无能为力:
- 接口要求
email字段,但响应里漏传了 age应该是整数,客户端却传了字符串"25"- 枚举字段
status出现了约定之外的值"unknown" - 嵌套对象
address.zip不符合邮编格式
JSON Schema 的价值在于:把上述「隐含约定」变成可执行、可共享、可版本管理的声明。团队可以在 Code Review 阶段就对照 Schema 检查接口变更,而不是等到联调或上线后才发现字段对不上。
JSON Schema 基本用法与示例
最简 Schema 需要声明 $schema(使用的规范版本)和根级 type。下面描述一个用户对象:name 必填字符串,age 可选非负整数。
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schemas/user.json",
"title": "User",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"description": "用户姓名"
},
"age": {
"type": "integer",
"minimum": 0,
"maximum": 150
},
"email": {
"type": "string",
"format": "email"
}
},
"required": ["name"],
"additionalProperties": false
}
对应合法的数据实例:
{ "name": "张三", "age": 28, "email": "zhang@example.com" }
若传入 { "age": 28 }(缺少必填 name),或 { "name": "李四", "extra": true }(additionalProperties: false 禁止额外字段),校验器会返回明确的错误路径与原因。
常用关键字速查
Draft 2020-12 中开发者最高频的关键字如下,写 Schema 时几乎都会用到:
| 关键字 | 作用 | 示例 |
|---|---|---|
| type | 声明数据类型 | "string" / "integer" / "object" |
| properties | 对象的字段定义 | { "id": { "type": "integer" } } |
| required | 必填字段列表 | ["id", "name"] |
| enum | 限定枚举值 | ["draft", "published"] |
| format | 常见字符串格式 | "email" / "date-time" |
| $ref | 引用其他 Schema 片段 | "#/$defs/Address" |
复杂 Schema 建议用 $defs 拆分可复用片段(如 Address、Pagination),再通过 $ref 引用,避免单文件膨胀。
JSON Schema 与 JSON 语法校验的区别
两者解决不同层次的问题,实践中通常组合使用:
- 语法校验:括号、引号、逗号是否合法 → 能否
JSON.parse - Schema 校验:字段、类型、约束是否符合约定 → 能否通过业务规则
推荐工作流:先把原始文本粘贴到 JSONSort 做格式化与语法检查,确认无误后再交给 ajv、fastjsonschema 等库做 Schema 验证。本地工具处理语法层,Schema 处理语义层,职责清晰。
实战:API 契约校验流程
以一个典型的 REST 项目为例,完整流程可以拆成四步:
-
定义 Schema:在仓库中维护
schemas/user.json,与 OpenAPI 或接口文档同步版本。 - 编写示例:提供一份合法与一份非法样例,作为单元测试 fixtures。
- CI 集成:在 PR 流水线里校验 Mock 响应与 Schema 是否匹配,防止字段被意外删除或改名。
- 运行时兜底:服务端在接收请求体时执行 Schema 校验,返回 400 与结构化错误,而不是把脏数据写入数据库。
这套流程的核心收益是变更可感知:接口字段改动会在 CI 阶段被捕获,而不是依赖人工记忆或联调时的偶然发现。
JSON Schema 与其他方案对比
| 方案 | 优点 | 局限 |
|---|---|---|
| JSON Schema | 语言无关、OpenAPI 原生支持、生态成熟 | 复杂规则表达力有限,学习曲线存在 |
| TypeScript 类型 | IDE 体验好,编译期检查 | 仅限 TS 生态,运行时需额外转换 |
| 手写 if/else 校验 | 灵活,无额外依赖 | 难维护、难复用、容易遗漏边界 |
| Protobuf / Avro | 强类型、高性能序列化 | 需要编译步骤,不适合纯 JSON API 场景 |
若你的 API 已经是 JSON + OpenAPI,JSON Schema 通常是最低摩擦的选型;若全栈 TypeScript 且不需要跨语言契约,可以 TS 为主、Schema 为辅。
JSON Schema 值得投入吗?
建议投入的场景:
- 对外提供 API,需要与调用方共享机器可读的契约
- 配置文件结构复杂,希望在部署前拦截格式错误
- 多端(Web / 移动端 / 后端)共用同一份数据约束
- 需要在 CI 中自动化检测接口 breaking change
可以暂缓的场景:
- 只是偶尔格式化或查看 JSON → 用 JSONSort 即可
- 数据结构极简且长期不变 → 手写校验成本更低
- 团队无 OpenAPI / 契约测试流程 → 先建立文档习惯再引入 Schema
常见问题(FAQ)
JSON Schema 是什么?
JSON Schema 是描述 JSON 数据结构与约束的规则集。它本身是一份 JSON 文档,用于声明字段类型、必填项、取值范围等,供校验器自动判断数据是否合法。
JSON Schema 和 JSON 有什么区别?
JSON 承载业务数据;JSON Schema 描述这份数据应该长什么样。类比:JSON 是「实例」,Schema 是「模具」。
应该选哪个版本?
新项目优先 Draft 2020-12。旧项目若已使用 Draft-07 / 2019-09,不必强行迁移,除非依赖新版本关键字。
如何在本地校验?
语法层用 JSONSort 格式化与检查;Schema 层用 ajv(Node.js)、jsonschema(Python)或 VS Code 的 JSON Schema 插件。
OpenAPI 和 JSON Schema 什么关系?
OpenAPI 3.x 的请求/响应体定义基于 JSON Schema 的子集并做了扩展。写好 OpenAPI 文档,本质上就在写 Schema。
结论
JSON Schema 解决的不是「JSON 能不能解析」,而是「数据是否符合团队约定」。从定义、写法到 CI 集成,它的价值在于把隐式规则变成显式、可执行的契约。建议从一个小型接口或配置文件入手,写第一份 Schema 并接入校验,再逐步扩展到全项目。
延伸阅读
- JSON Schema 官方规范 权威关键字与版本说明
- JSONSort 本地 JSON 工具箱 格式化、语法校验、Diff — 浏览器本地运行
- 博客全部文章 更多 JSON 开发教程与实践经验
更新日志: 初稿发布