联调前先验 JSON:用 Schema 在浏览器里卡住坏数据

前后端对齐接口时,常见节奏是:文档里列了字段 → 后端先按理解实现 → 前端拿 Postman 或浏览器试一圈 → 发现少了一个 age、多了一层嵌套、某个字段从字符串变成了数字。问题往往不在谁粗心,而是文档和示例本身就不是可执行的契约。

JSON Schema 用一段 JSON 描述「合法数据长什么样」。校验器(例如 ajv)拿真实 payload 去对照,不通过就给出路径和原因。还没部署、也还没写集成测试时,可以在浏览器里先验一遍——不绑 CI,也不一定要先写脚本。

本站放在 数据处理 · JsonSchema:左边数据、右边 Schema。标题旁有「从 URL 导入」,跨域会走 /api/schema-fetch。右侧 Schema 自身合法后,左侧改数据会边编辑边标错;点「校验」用 ajv 汇总到底部结果区,能映射到源码的错误可以点一下跳到左侧。第二节示例与工具默认右侧一致;第三节样例请自己贴到左侧试(预填的是另一份用户列表示例)。

为什么不是「能 JSON.parse 就行」

JSON.parse 只管语法,不管必填、类型、数组元素是否同构、枚举是否合法。

Schema 管形状。业务规则(比如是否满 18 岁)仍要代码判断,但字段缺失、类型明显不对这类问题不必放进业务里再暴雷。

和 TypeScript 相比,Schema 更适合跨团队、跨语言的接口边界——各方对着同一份 JSON 描述对齐,比对着 Word 表格猜省事。

最小 Schema 示例

多数 payload 根上是 object,起步三个词够用:

关键词作用
type根或字段类型
properties有哪些字段、各是什么类型
required哪些必现(未列入 required 的字段仍可出现,除非设了 additionalProperties: false)

示例:根必须有 users 数组;每项必须有 name(string)和 age(number)。

JSON
{
  "type": "object",
  "required": ["users"],
  "properties": {
    "users": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["name", "age"],
        "properties": {
          "name": { "type": "string" },
          "age": { "type": "number" },
          "email": { "type": "string" }
        }
      }
    }
  }
}

email 只在 properties 里声明了类型,没写进 required,缺了也能过——写出来 ≠ 必填,很多人都会在这里栽一次。

通过和不通过

能通过:

JSON
{
  "users": [
    { "name": "Alice", "age": 25, "email": "alice@example.com" },
    { "name": "Bob", "age": 30 }
  ]
}

不能通过(第二条缺 age):

JSON
{
  "users": [
    { "name": "Alice", "age": 25 },
    { "name": "Bob" }
  ]
}

点「校验」后,底部大致是(英文措辞随 ajv 版本略有差别):

TEXT
校验未通过
/users/1: must have required property 'age'

/users/1 即下标 1 的元素;点这行可在左侧定位。

类型错了也一样,例如:

JSON
{
  "users": [{ "name": "Alice", "age": "25" }]
}

往往会指到 /users/0/age。改数据或改 Schema,别在代码里悄悄兼容。

联调前怎么用

从文档抠最小 Schema 即可,先 required 加本轮真用到的字段,再慢慢收紧。手边放两三份 JSON:文档示例、故意写错的、测试环境抓包(脱敏)。同一右侧 Schema,左侧换数据逐份点「校验」。

过得去的 Schema 建议进仓库。浏览器验给人看;CI 用同一份挡回归,不冲突。oneOf、$ref、format、draft 差别这类进阶话题需要时再查;外站拷来的 Schema 报错,先核对 draft 和 ajv 是否吃这套关键字。

和站内其它工具

场景做法
JSON 很乱格式转换,或 dataproc · 清理数据 里格式化
只验一段JsonPath 取子树,再进 JsonSchema
两版差在哪文本对比 看 diff;Schema 看是否符合同一份契约

Schema 说合不合法,Diff 说两次输出一不一样,初期经常都要看。


手头正对的接口,不妨现在就试:左侧贴响应,右侧十来行 Schema(或 URL 导入),点「校验」,把路径发给对方。比「我这边显示不对」少扯几轮。

返回博客