在发起 API 请求前校验 JSON

在发送 API 请求前做一次快速校验,可以把 JSON 语法问题与认证、Schema、后端错误清晰地区分开。

为什么发送前先校验

API 请求失败时,错误信息可能指向认证、权限、schema 校验或 JSON 本身的语法问题。先校验 JSON body,就能在请求送到服务器之前排除整整一类失败。它也让复制的 cURL、Postman body、webhook 样例、集成测试在 review 时更友好。

要做的语法检查

一次严格的 JSON 校验应该确认 body 能解析为 JSON,并且格式化后的输出和你打算发送的一致。

  • 每个字符串和对象键都用双引号
  • 没有注释或尾随逗号
  • 布尔值是 true 或 false,而不是 True 或 False
  • 缺失值是 null 或干脆省略,而不是 undefined
  • 顶层值与目标 endpoint 的期望一致

请求头同样重要

一份合法的 JSON body 如果请求声明的 Content-Type 不对,仍然会失败。大多数 JSON API 都要 Content-Type: application/json。如果 endpoint 还检查 Accept,加上 Accept: application/json,让客户端和服务端就负载格式达成一致。

出错的请求体

{ userId: 42, active: True, tags: ['beta',], }

修复后的请求体

{ "userId": 42, "active": true, "tags": ["beta"] }

语法校验之后

语法校验只能证明文档可解析。对于生产请求,还要检查 schema:必填字段、未知字段、值类型、数组长度、枚举值、日期字符串,以及数字 ID 应该是数字还是字符串。

调试小技巧

如果服务端仍然拒绝合法的 JSON,把格式化后的请求体与已知可用的样例做对比。语义化的 JSON diff 能在忽略键序的同时找出真正的值变化,对不同工具生成的负载尤其有用。

一个小巧的 fetch + Ajv 封装

在把响应体交给业务代码前,先按已知 schema 校验。模块加载时把 schema 编译一次,然后每次调用都加一层保护:const validate = ajv.compile(schema); const res = await fetch(url); const data = await res.json(); if (!validate(data)) throw new Error("Schema mismatch: " + ajv.errorsText(validate.errors)); return data; —— 这样上游合约破坏会在边界暴露,而不是埋到五层之下。