关于 validating-json-data
validating-json-data 是一项技能,介绍如何使用 z-schema 按 JSON Schema 验证 JSON 数据。内容包括验证模式、错误检查、架构编译与引用、自定义格式,以及多个架构草案的支持。
主要功能
- 01支持五种架构草案
- 02同步与异步验证模式
- 03安全结果与详细错误
- 04架构编译和引用
- 05自定义同步或异步格式
适用场景
- 01在脚本或中间件中验证 JSON
- 02输出结构化验证错误
- 03使用自定义格式规则检查数据
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ zaggino/ z-schema --skill validating-json-data安装后在 Claude Code 中输入/validating-json-data确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/draft-comparison.mderror-codes.mdoptions.md详细介绍
使用 z-schema 验证 JSON 数据
z-schema 可根据 JSON Schema(draft-04、draft-06、draft-07、draft-2019-09、draft-2020-12)验证 JSON 数据。默认草案版本:draft-2020-12。
快速开始
import ZSchema from 'z-schema';
const validator = ZSchema.create();
const schema = {
type: 'object',
properties: {
name: { type: 'string' },
age: { type: 'integer', minimum: 0 },
},
required: ['name'],
};
// Throws on invalid data
validator.validate({ name: 'Alice', age: 30 }, schema);
安装:npm install z-schema
选择验证模式
z-schema 基于两个开关:async 和 safe,提供四种模式。请选择适合使用场景的模式。
| 模式 | 工厂调用 | 返回值 | 适用场景 |
|---|---|---|---|
| 同步抛出异常 | ZSchema.create() | true 或抛出 ValidateError | 默认模式——简单脚本和中间件 |
| 同步安全模式 | ZSchema.create({ safe: true }) | { valid, err? } | 需要检查错误且不使用 try/catch 时 |
| 异步抛出异常 | ZSchema.create({ async: true }) | Promise<true> 或拒绝 | 使用异步格式验证器时 |
| 异步安全模式 | ZSchema.create({ async: true, safe: true }) | Promise<{ valid, err? }> | 异步且不抛出异常时 |
同步抛出异常(默认)
import ZSchema from 'z-schema';
const validator = ZSchema.create();
try {
validator.validate(data, schema);
} catch (err) {
// err is ValidateError
console.log(err.details); // SchemaErrorDetail[]
}
同步安全模式
const validator = ZSchema.create({ safe: true });
const result = validator.validate(data, schema);
if (!result.valid) {
console.log(result.err?.details);
}
或者,在常规(会抛出异常的)验证器上调用 .validateSafe(),即可获得相同的结果格式:
const validator = ZSchema.create();
const { valid, err } = validator.validateSafe(data, schema);
异步抛出异常
使用异步格式验证器时必须启用。
const validator = ZSchema.create({ async: true });
try {
await validator.validate(data, schema);
} catch (err) {
console.log(err.details);
}
异步安全模式
const validator = ZSchema.create({ async: true, safe: true });
const { valid, err } = await validator.validate(data, schema);
检查错误
ValidateError 包含 .details,这是一个 SchemaErrorDetail 数组:
interface SchemaErrorDetail {
message: string; // "Expected type string but found type number"
code: string; // "INVALID_TYPE"
params: (string | number | Array<string | number>)[];
path: string | Array<string | number>; // "#/age" or ["age"]
keyword?: string; // "type", "required", "minLength", etc.
inner?: SchemaErrorDetail[]; // sub-errors from anyOf/oneOf/not
schemaPath?: Array<string | number>;
schemaId?: string;
}
示例:遍历嵌套错误
组合器(anyOf、oneOf、not)会产生嵌套的 inner 错误:
const { valid, err } = validator.validateSafe(data, schema);
if (!valid && err) {
for (const detail of err.details) {
console.log(`${detail.path}: [${detail.code}] ${detail.message}`);
if (detail.inner) {
for (const sub of detail.inner) {
console.log(` └─ ${sub.path}: [${sub.code}] ${sub.message}`);
}
}
}
}
筛选错误
将 ValidateOptions 作为第三个参数传入,以包含或排除特定错误代码:
// Only report type errors
validator.validate(data, schema, { includeErrors: ['INVALID_TYPE'] });
// Suppress string-length errors
validator.validate(data, schema, { excludeErrors: ['MIN_LENGTH', 'MAX_LENGTH'] });
完整错误代码列表请参阅 references/error-codes.md。
预编译 Schema
在启动时编译 Schema,以提升运行时性能并解析交叉引用:
const validator = ZSchema.create();
const schemas = [
{
id: 'address',
type: 'object',
properties: { city: { type: 'string' }, zip: { type: 'string' } },
required: ['city'],
},
{
id: 'person',
type: 'object',
properties: {
name: { type: 'string' },
home: { $ref: 'address' },
},
required: ['name'],
},
];
// Compile all schemas (validates them and registers references)
validator.validateSchema(schemas);
// Validate data using a compiled schema ID
validator.validate({ name: 'Alice', home: { city: 'Paris' } }, 'person');
远程引用
手动注册
ZSchema.setRemoteReference('http://example.com/schemas/address.json', addressSchema);
// or per-instance:
validator.setRemoteReference('http://example.com/schemas/person.json', personSchema);
通过 Schema reader 自动加载
import fs from 'node:fs';
import path from 'node:path';
ZSchema.setSchemaReader((uri) => {
const filePath = path.resolve(__dirname, 'schemas', uri + '.json');
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
});
诊断缺失的引用
const { valid, err } = validator.validateSafe(data, schema);
if (!valid && err) {
const missing = validator.getMissingReferences(err);
const remote = validator.getMissingRemoteReferences(err);
}
自定义格式验证器
全局(所有验证器实例共享)
ZSchema.registerFormat('postal-code', (value) => {
return typeof value === 'string' && /^\d{5}(-\d{4})?$/.test(value);
});
实例范围
const validator = ZSchema.create();
validator.registerFormat('postal-code', (value) => {
return typeof value === 'string' && /^\d{5}(-\d{4})?$/.test(value);
});
创建时通过选项设置
const validator = ZSchema.create({
customFormats: {
'postal-code': (value) => typeof value === 'string' && /^\d{5}(-\d{4})?$/.test(value),
},
});
异步格式验证器
返回 Promise<boolean>。需要设置 { async: true }。
const validator = ZSchema.create({ async: true });
validator.registerFormat('user-exists', async (value) => {
if (typeof value !== 'number') return false;
const user = await db.findUser(value);
return user != null;
});
列出已注册的格式
const formats = ZSchema.getRegisteredFormats();
选择草案版本
如果 Schema 针对特定版本,请明确设置草案版本:
const validator = ZSchema.create({ version: 'draft-07' });
有效值:'draft-04'、'draft-06'、'draft-07'、'draft2019-09'、'draft2020-12'(默认值)、'none'。
各草案的功能比较请参阅 references/draft-comparison.md。
常用选项
| 选项 | 默认值 | 用途 |
|---|---|---|
breakOnFirstError | false | 在第一个错误处停止验证 |
noEmptyStrings | false | 拒绝将空字符串作为 string 类型 |
noEmptyArrays | false | 拒绝将空数组作为 array 类型 |
strictMode | false | 一次性启用所有严格检查 |
ignoreUnknownFormats | false | 忽略未知格式错误(现代草案始终忽略) |
formatAssertions | null | null=始终断言,true=遵循词汇表,false=仅作注释 |
reportPathAsArray | false | 将错误路径报告为数组,而非 JSON Pointer 字符串 |
完整选项参考请参阅 references/options.md。
验证子模式
指定模式中的特定路径:
validator.validate(carData, fullSchema, { schemaPath: 'definitions.car' });
浏览器用法(UMD)
<script src="node_modules/z-schema/umd/ZSchema.min.js"></script>
<script>
var validator = ZSchema.create();
try {
validator.validate({ name: 'test' }, { type: 'object' });
} catch (err) {
console.log(err.details);
}
</script>
TypeScript 类型
所有类型均从此软件包导出:
import type {
JsonSchema, // Schema type (all drafts union)
ZSchemaOptions, // Configuration options
ValidateOptions, // Per-call options (schemaPath, includeErrors, excludeErrors)
ValidateResponse, // { valid: boolean, err?: ValidateError }
SchemaErrorDetail, // Individual error detail
ErrorCode, // Error code string literal type
FormatValidatorFn, // (input: unknown) => boolean | Promise<boolean>
SchemaReader, // (uri: string) => JsonSchema
} from 'z-schema';
import { ValidateError } from 'z-schema';
参考文件
- references/error-codes.md — 完整的错误代码列表,附带说明和示例
- references/options.md — 完整的选项参考,包含默认值
- references/draft-comparison.md — 各 JSON Schema 草案之间的功能比较
重要约定
- 始终使用
ZSchema.create(options?),不要使用new ZSchema()。此工厂会返回类型正确的变体。 - 错误详情位于
.details(而非.errors)。 - 使用
import type { ... }导入类型,使用import { ValidateError }导入值。 - 默认草案为
draft2020-12。若目标是较早的草案,请明确指定。