JSON 工具 · 6 分钟阅读
JSON 到 JSON 模式:从样本有效负载到合约
JSON 到 JSON 模式转换采用了一个可以工作并生成其形状的机器可读描述的示例。该描述可以验证未来的有效负载、生成文档或驱动类型化代码 - 但前提是您将生成的模式视为初稿。推断看到一个样本,一个样本就是一个非常自信的骗子。
已更新
推论能看到什么和不能看到什么
一个好的转换器可以从单个文档中准确地导出类型、嵌套、数组项形状和属性名称。它无法得出的是意图。它不知道某个字段是可选的,因为该特定记录碰巧包含该字段,也不知道字符串是电子邮件地址,数字是正整数,或者值来自固定集。因此,导出的所有内容都被标记为 `required`,这是合同草案的正确默认值,并且未经审查就发货是错误的。
强化生成的模式
- 比较两个或三个真实样本:任何样本中缺失的键都应落在 `required` 范围内。
- 在已知含义的地方添加 `format` — `date-time`、`email`、`uri`、`uuid`、`ipv4`。
- 当该字段确实具有固定词汇(例如状态或区域)时,将开集转换为 `enum` 值。
- 用 `minimum`、`maximum` 和 `multipleOf` 收紧数字,这样负数就无法验证。
- 仅当必须拒绝未知密钥时才添加 `additionalProperties: false` — 否则保持模式开放以实现前向兼容性。
需要的是一个承诺,而不是一个观察。将某个字段标记为必填字段,因为您的一个样本包含该字段,这是推断模式破坏真实集成的最常见方式。
模式的立足点
实用价值体现在边界上:在信任 Webhook 有效负载之前对其进行验证,检查 CI 中的固定文件,以便测试因格式错误的数据而不是令人困惑的空错误而失败,为永远不会阅读服务器代码的人记录 API 响应,以及生成类型化客户端。 JSON 模式也是阻止配置更改悄悄改变公共响应的最便宜的方法,因为验证器在构建时而不是在生产中捕获它。
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["id", "email"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"email": { "type": "string", "format": "email" },
"plan": { "type": "string", "enum": ["free", "pro", "team"] }
}
}
将其保留在版本控制中
生成的模式一旦没有人拥有它们,就会发生漂移。将强化文件提交到生成数据的代码旁边,从 CI 中的验证器引用它,并仅在合约真正更改时重新生成 - 将模式视为形状的真实来源,将样本视为证据,而不是相反。
浏览器中的推理
真实的有效负载充满了标识符、电子邮件和令牌,因此上传示例的 JSON 到 JSON 模式转换正在将生产数据移交给纯粹的机械操作。本地推断将有效负载保留在选项卡中,让您可以毫不犹豫地粘贴客户记录,并且可以在网络断开的情况下工作。
JSON 至 JSON 架构 — 常见问题
为什么每个字段都按要求输出?
因为推理会看到一个样本,并且该样本包含每个字段。必需意味着保证,因此生成的模式是一个起点:比较几个样本,然后删除有时不存在的键,并在您知道真正规则的地方添加 `format` 或 `enum` 约束。
我应该使用哪个 JSON 架构草案?
新工作的 2020-12 草案 — 这是当前规范,并得到 ajv 等验证者的良好支持。如果您要与固定到草案 07 的系统集成,请继续生成草案 07 文档;两者的主要区别在于您可能不需要的新关键字。
JSON 模式也可以验证数组吗?
是的。数组推断会生成描述元素形状的 `items` 模式,并且在现代草稿中可以使用 `prefixItems` 检查单个元素形状。合并两个具有不同元素形状的样本,您将看到哪里需要 `oneOf`。
这篇文章中提到的工具
更多文章可供阅读
6 分钟阅读
JSON至TypeScript:符合实际的类型
将真实 API 响应(可选键、空联合、嵌套类型)的 JSON 接口转换为 TypeScript 接口,并防止生成的类型发生漂移。
6 分钟阅读
JSON 格式化程序:漂亮、精简且有效
一个 JSON 格式化程序,可以漂亮地打印、缩小并验证准确的错误位置 - 加上几乎每个无效 JSON 错误背后的五个语法错误。
6 分钟阅读
JSON diff:比较数据的实际结构
将两个 JSON 有效负载与结构性 JSON 差异进行比较,忽略按键顺序和空格,突出显示移动的值,并说明文本差异为何会产生误导。
- 较长的文章可供阅读: JSON 至 TypeScript:说实话的类型