JSON 工具箱

JSON Schema 到底能解决什么问题

结论:Schema 管的是结构和类型,管不了业务语义。它能把「字段缺失、类型错、枚举越界」挡在入口,但「金额为负、结束时间早于开始时间」这类规则,得靠代码校验。

进阶约 4 分钟发布于 2026-10-30更新于 2026-10-30
JSON Schema 的能力边界与适用场景

结论:JSON Schema 负责结构、类型、取值范围与格式,跨字段依赖、业务不变量和外部状态必须放回代码;接口对外开放或多服务共享数据时引入,内部小服务字段少时手写判断更快。

能解决「这份数据长得对不对」,解决不了「这份数据说得通不通」。

它擅长的部分

结构完整性。 该有的字段有没有,多余的字段允不允许(required、additionalProperties)。

类型正确性。 port 是数字还是字符串,tags 是数组还是单个值。跨语言系统里这一条能省掉大量类型判断代码。

取值范围。 枚举(enum)、数值区间(minimum/maximum)、字符串长度(minLength/maxLength)、数组长度(minItems)。

格式约束。 日期、邮箱、URI、UUID 这些有公认写法的字段,用 format 声明,配合支持断言 format 的校验器使用。

嵌套结构。 对象里套对象、数组里套对象,每一层都能单独约束,错误信息能精确到路径。

契约文档化。 Schema 本身就是接口文档,改字段必须改 Schema,评审时一眼能看出影响范围。它还能反向生成 TypeScript 类型、Go 结构体、表单配置,属于「一处定义、多处消费」。

它管不了的部分

跨字段依赖。 「结束时间必须晚于开始时间」「A 字段为 true 时 B 才必填」,JSON Schema 的 if/then/else 能强行表达一部分,但写出来又长又难读,维护成本高于直接在代码里写三行判断。

业务不变量。 「库存不能为负」「同一订单号不能重复」,这依赖外部状态,Schema 只看单份数据,看不见数据库。

语义正确性。 price: -100 完全符合 {"type": "number"},但它是不是合法的价格,Schema 不知道。

性能与体积。 Schema 不限制请求体大小,也不管嵌套深度攻击,这些要在网关层做。

一个实用的分工

层次 谁负责
语法:是不是合法 JSON 解析器
结构:字段、类型、范围、格式 JSON Schema
语义:跨字段、业务规则、外部状态 业务代码
安全:体积、深度、频率 网关 / 中间件

把四层混在一起做,最常见的后果是 Schema 膨胀到几百行、if/then 嵌套五六层,改一个字段要半天,最后大家绕开校验直接改代码。

什么时候值得引入

  • 接口对外开放,调用方不可控
  • 多个服务消费同一份数据,结构漂移会连锁出错
  • 配置驱动,需要在校验阶段拦住手写错误
  • 需要用 Schema 反向生成类型或表单

如果只是一个内部小服务、字段三五个、调用方就一个前端,写 if 判断比维护 Schema 更快——这时候引入 Schema 是负收益。

常见问题

如何判断一个项目该不该引入 JSON Schema?

看接口是否对外开放、是否有多个服务消费同一份数据、是否需要反向生成类型或表单。若是内部小服务、字段三五个、调用方只有一个前端,写 if 判断比维护 Schema 更快。

为什么跨字段规则不该硬写进 Schema?

「结束时间必须晚于开始时间」这类规则虽然能用 if/then/else 表达,但写出来又长又难读,维护成本高于直接在代码里写三行判断。

是否可以用 Schema 校验请求体大小和嵌套深度?

不能。Schema 只看数据结构,不限制体积与深度,这类安全约束要在网关或中间件层处理。

相关工具

延伸阅读