JSON Schema 校验

左边贴 schema,右边贴数据,逐条列出不匹配的路径和原因,改完立刻重新校验。

校验规则

这里用 Ajv 校验:没写 $schema 时按 draft-07 编译,写了 2019-09 或 2020-12 就切换到对应的校验器。只会解析同一份文档里的 $ref,远程引用不会去取。schema 本身语法错误时,会直接给出编译失败的原因,不会拿一份坏 schema 去校验数据。

错误路径是 JSON Pointer,/items/0/name 表示 items 数组第一个元素的 name 字段,空字符串代表根节点。先看路径定位数据,再看关键字判断是类型问题还是约束问题。

format 默认不强制校验,邮箱、日期这类内容只检查是不是字符串。要生成 schema 用JSON 转 JSON Schema,要把 schema 变成 TypeScript 类型用JSON Schema 转 TypeScript,格式化数据用JSON 格式化。

常见问题

为什么格式校验没有生效?

format 在 JSON Schema 里默认是注解,不强制校验。这里没有引入 ajv-formats,所以 email、date-time 这类只会检查类型,不会检查内容是否符合格式。需要强校验时在服务端补上 format 插件。

additionalProperties: false 报了一堆错?

它表示只允许 properties 里声明过的字段。对象里多一个字段就会报错,常见于接口加了新字段但 schema 没同步。排查时先看错误里的 additionalProperty,再决定是补 schema 还是删数据。

支持 $ref 引用别的文件吗?

只支持同一份 schema 内部的 $ref(#/definitions/... 或 #/$defs/...)。远程 URL 和相对路径引用不会去解析,遇到时会报找不到引用。多文件 schema 建议先用工具打包成一份再校验。

为什么数字 1 能通过 integer 校验?

JSON Schema 的 integer 指数学意义上的整数,1.0 在 JSON 里解析后就是 1,和 JavaScript 的判断一致。要区分整数字面量,只能靠原始文本或自定义关键字。

draft-04 的 schema 能校验吗?

Ajv 默认按 draft-07 编译,draft-04 的 exclusiveMinimum 是布尔值,语义和后来的版本不同,可能报 schema 编译错误。老 schema 建议先升级到 draft-07 或 2020-12。

校验通过就能放心用了吗?

schema 只描述结构,不保证业务正确:金额是否为负、开始时间是否早于结束时间、ID 是否真的存在,这些都要在代码里另外校验。schema 是第一道门,不是全部。