JSON Schema 生成器
从您的数据自动生成 JSON Schema
JSON Schema 生成器读取一份 JSON 样例文档,生成描述其结构的 Draft-07 Schema:类型、嵌套对象和数组。它面向希望不手写每个属性就获得校验起点的 API 开发者,以及需要快速为 JSON 负载写文档的团队。
使用方法
把样例粘贴到输入框,或点击样例按钮载入一个演示对象。点击生成。工具会解析 JSON、遍历结构,并把格式化后的 Schema 打印到输出框。检查结果,然后把它复制进校验器、契约测试或文档。无效的 JSON 会报错,而不会产出残缺的结果。
生成的 Schema 包含什么
输出总是以 "$schema": "http://json-schema.org/draft-07/schema#" 开头。除此之外它还会生成:
- 每个节点的
type:object、array、string、integer、number、boolean 或 null。 - 每个对象每个键的
properties,递归进行。 - 数组的
items,根据第一个元素推断。
它不会生成 required、enum、format、pattern、数值边界或 oneOf。这些关键字在底层库里是存在的,但页面所用的生成路径只会产出 type、properties 和 items。请把结果当成一个结构骨架,之后再补上你真正的约束。
实操示例
输入:
{
"name": "John Doe",
"age": 30,
"isActive": true,
"tags": ["developer", "designer"],
"address": { "city": "San Francisco", "zipCode": "94105" }
}
输出(有删节):
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer" },
"isActive": { "type": "boolean" },
"tags": { "type": "array", "items": { "type": "string" } },
"address": {
"type": "object",
"properties": {
"city": { "type": "string" },
"zipCode": { "type": "string" }
}
}
}
}
由于没有 required 数组,校验器会把 {} 视为合法。这通常不是你想要的,所以要手动加上 "required": ["name", "address"] 以及任何 format 规则。
Draft-07 与兼容性
Draft-07 是一个被广泛支持的方言。Ajv 在 JavaScript 中支持它,Python 的 jsonschema 包也支持它,多数 schema 工具仍接受它。较新的规范如 2020-12 改动了一些关键字,而 OpenAPI 3.1 基于 2020-12,因此 Draft-07 的 Schema 在干净地放进 OpenAPI 3.1 文件之前可能需要小幅修改。$schema 那行告诉使用者该用哪种方言,所以请保留它。Draft-07 还允许布尔 Schema 以及 if、then、else 这类条件关键字;生成器不会产出它们,但你可以手动添加。
应当了解的推断局限
只检查数组的第一个元素。像 [{"a":1},{"b":2}] 这样的数组会被描述为「带有属性 a 的对象的 items」,第二种形状完全看不到。空数组会得到空的 items,不构成任何约束。每个字符串都是普通的 string,没有 format,所以邮箱、日期和 UUID 看起来一模一样。null 会被保留为 type: null,在严格校验器里只允许 null;如果一个字段有时为 null、有时是字符串,Schema 对其中一种情况必然是错的。源码中的重复键会被 JSON.parse 处理,只保留最后一次出现。最后,由于推断基于单个示例,今天恰好是整数的字段会被锁定为 integer,即使 API 以后返回小数。对象键的顺序与样例一致,但属性顺序对校验没有意义;输入必须是严格 JSON,因此注释和尾随逗号都会被拒绝。
把骨架扩展为真正的校验
生成的 Schema 能解析,但它本身接受的东西太多。通常的下一步是补上 required 字段、format 和边界。
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["name", "address"],
"properties": {
"name": { "type": "string", "minLength": 1 },
"age": { "type": "integer", "minimum": 0, "maximum": 150 },
"email": { "type": "string", "format": "email" },
"isActive": { "type": "boolean" }
}
}
为必须始终存在的字段加上 required。为表示邮箱、日期或 URI 的字符串加上 format,但记住有些校验器在未显式开启 format 断言时会忽略它。为单个样例无法揭示的规则加上 minimum、maximum、minLength 和 pattern。
如果你有多份样例,请手动合并。页面背后的库能够检测每份样例都出现的键、从少量重复值构建 enum,并用 oneOf 合并不同形状,但页面只喂给它一份文档。这些细化工作要你自己做。要真正执行校验,把文件保存为 schema.json,在 JavaScript 中用 Ajv 编译它,或在 Python 中调用 jsonschema.validate(instance, schema)。
常见错误
指望生成器标出必填字段。只喂一个最小示例,却假定 API 可能返回的每个属性都会出现。依赖它检测类似 enum 的值、字符串 format 或数值范围。粘贴一个记录数组,却以为所有记录都被分析过。以及把原始输出当作生产校验直接上线,而不补上样例无法表达的约束。还有一种:粘贴一个本身包含 JSON 的 JSON 字符串,却期望内部文档被描述;实际上只会推断出顶层的 string 类型。
相关工具
常见问题
为什么生成的 Schema 里没有 required 数组?
生成器只从单个 JSON 值推断结构,因此它看到的每个键都被当作可选。它根本不会输出 required 列表。对必须始终存在的字段,你需要自己补上 required。
它面向哪个草案版本?能用于 OpenAPI 3.1 吗?
输出通过 $schema 声明 Draft-07。Ajv、Python 的 jsonschema 以及大多数校验工具都接受它。OpenAPI 3.1 改用 JSON Schema 2020-12,所以请把生成的 Schema 当作起点;如果要粘进 OpenAPI 3.1 文档,需要相应调整方言。
工具如何决定用 integer 还是 number?
它检查每个数值是否为整数。样例里出现 30 且没有小数点就会推断为 integer;像 3.14 这样的值则推断为 number。一个可能两者皆有的属性,会按这一份样例里的实际取值来定类型。
它会检查数组的每一个元素吗?
不会。对数组值,生成器只检查第一个元素并用它来描述 items。后面形状不同的元素会被忽略,混合类型的数组也不会被表示成 oneOf。
它能识别 email、date-time 或 UUID 这些 format 吗?
不能。每个字符串都只是 type string,不带任何 format 关键字。仅从值本身推断无法区分邮箱地址和普通句子,所以 format、pattern 或长度约束都要手动添加。
遇到空对象或空数组会怎样?
空对象会生成 type object 和一个空的 properties 映射。空数组会生成 type array 和空的 items,因为没有第一个元素可供检查。
由 HandyTools Hub 团队审校 · 最后更新