Ajv 实战:Node.js JSON Schema 校验指南

Ajv 是 Node.js 生态的 JSON Schema 校验器,把 Schema 编译成可复用的校验函数;实际性能取决于 Schema、数据和配置。本文讲解 Ajv 的安装、Schema 编写、格式校验、自定义规则与错误信息处理。

最佳实践
应用接口与数据存储连接插画

Ajv 把 JSON Schema 编译成高度优化的 JavaScript 函数来校验数据,适合需要复用标准 Schema 的 Node.js 项目。基本用法三步:new Ajv() 创建实例、ajv.compile(schema) 编译 Schema、调用编译出的函数校验数据——返回 false 时从 validate.errors 读取逐条错误明细。

为什么是 Ajv

JSON Schema 是描述数据结构的标准,而 Ajv 是它在 Node.js 的事实标准实现:Fastify 等框架内建用它做请求校验。性能秘诀在于编译而非解释——Schema 只编译一次,之后每次校验就是跑一个为这份 Schema 量身定制的函数。

安装与快速开始

npm install ajv ajv-formats
const Ajv = require('ajv');
const addFormats = require('ajv-formats');

const ajv = new Ajv({ allErrors: true });
addFormats(ajv);   // 启用 email、uri、date-time 等格式校验

const schema = {
  type: 'object',
  properties: {
    name: { type: 'string', minLength: 1 },
    email: { type: 'string', format: 'email' },
    age: { type: 'integer', minimum: 0 }
  },
  required: ['name', 'email'],
  additionalProperties: false
};

const validate = ajv.compile(schema);

const ok = validate({ name: '观测云', email: 'a@b.com' });
if (!ok) console.log(validate.errors);

allErrors: true 让校验跑完全程返回所有错误(默认遇到第一个就停),对用户表单更友好。additionalProperties: false 禁止 Schema 未声明的字段,是防止脏数据渗入的关键开关。

常用规则速查

  • 字符串:minLength/maxLength/pattern(正则)/format(email、uri、date-time、uuid);
  • 数字:minimum/maximum/exclusiveMinimum/multipleOf;
  • 数组:items(元素 Schema)/minItems/uniqueItems;
  • 枚举与常量:enum: ['a', 'b']、const: 'v1';
  • 条件组合:anyOf(任一满足)/oneOf(恰好一个)/allOf(全部满足)/if-then-else 条件分支。

自定义校验规则

内置规则不够用时,用 addKeyword 扩展:

ajv.addKeyword({
  keyword: 'isPhone',
  type: 'string',
  schemaType: 'boolean',
  validate: (schemaVal, data) => !schemaVal || /^1\d{10}$/.test(data),
  errors: false
});

const schema = { type: 'string', isPhone: true };

这里仅检查以 1 开头的 11 位数字外形,不验证号码分配或可用性。

复杂跨字段校验(如"结束时间必须大于开始时间")也可以直接用代码函数实现,比纯 Schema 表达更直观。

错误信息的可读化

validate.errors 是结构化数组(instancePath + message),直接抛给用户太生硬。生产实践:写一个格式化函数把 errors 映射成 { 字段: 中文提示 } 结构,或引入 ajv-errors 在 Schema 里直接声明自定义错误消息。

常见问题(FAQ)

Q:Ajv 和 Zod/Joi 怎么选?

Ajv 是"JSON Schema 标准的实现",Schema 可跨语言共享、与 OpenAPI 的兼容性需按其版本和 Schema 方言核对;Zod 是 TypeScript 优先的体验派(类型自动推导);Joi 语法链式友好。Fastify 生态选 Ajv,TS 全栈选 Zod,详见本系列 Joi、Zod 对比篇。

Q:为什么 format: 'email' 不生效?

Ajv 从 v7 起把 format 拆成独立包:必须 npm i ajv-formats 并 addFormats(ajv),默认遇到未知 format 会在编译 Schema 时抛错;strict: false 不会补上实际格式校验。

Q:Strict 模式报错怎么关闭?

new Ajv({ strict: false }),但建议保持开启并修正 Schema——strict 拦下的多是 Schema 写法的真实问题(如未声明的 type),关掉等于蒙眼开车。


参考文档

本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台