Skip to main content

ajv

caution
npm add ajv ajv-formats ajv-keywords ajv-errors
import addFormats from 'ajv-formats';
import addKeywords from 'ajv-keywords';
import Ajv2020 from 'ajv/dist/2020';

const ajv = new Ajv2020();
addFormats(ajv);
addKeywords(ajv);

// 添加自定义 keyword 避免失败
ajv.addKeyword('x-meta');
formatexampledescription
ajv-formats
date2021-01-01RFC3339 full-date
time14:30:00+01:00time with optional time-zone.
date-time2021-01-01T14:30:00+01:00date-time from the same source (time-zone is mandatory).
durationP3Y6M4DT12H30M5SRFC3339 duration
urihttps://example.comfull URI.
uri-reference/relative/uriURI reference, including full and relative URIs.
uri-templatehttps://example.com/{user}RFC6570 URI template
urlhttps://example.comURL record
emailuser@example.comemail address.
hostnameexample.comRFC1034 host name
ipv4192.168.0.1IPv4
ipv62001:0db8:85a3:0000:0000:8a2e:0370:7334IPv6
regex^[a-zA-Z0-9]+$RegExp
uuid123e4567-e89b-12d3-a456-426614174000RFC4122 UUID
json-pointer/pointerRFC6901 JSON-pointer
relative-json-pointer0draft relative JSON-pointer
ajv-formats-draft2019
irihttps://例子.测试RFC3987 IRN/Internationalized Resource Identifier
iri-reference/relative/路径IRI reference, including full and relative IRIs.
idn-hostname例子.测试RFC5890 IDN/Internationalized Domain Name hostname
idn-email用户@例子.测试RFC6531 Internationalized email address
// 自定义 format
ajv.addFormat('identifier', /^a-z\$_[a-zA-Z$_0-9]*$/);
// 使用自定义逻辑校验 format
ajv.addFormat('byte', {
type: 'number',
validate: (x) => x >= 0 && x <= 255 && x % 1 == 0,
});
ajv.addFormat('int8', {
type: 'number',
validate: (x) => x >= -128 && x <= 127 && Number.isInteger(x),
});

standalone validation code

  • 生成独立的函数
npm install -g ajv-cli
ajv compile -s schema.json -o validate_schema.js

addKeyword

FAQ

due to error strict mode: unknown keyword

ajv schema with key or id already exists

  • 如果 schema 有 $id 可能会出现
  • 如果 schema 是通过反序列化生成的,可能会出现重复 - ref 不一样但 id 一样

strict mode: unknown keyword

未知关键字,需要添加关键字支持

修改校验数据

类似 zod.parse 能得到一个解析后的满足验证要求的对象,不过 zod 不会修改传入对象,ajv 只能通过修改传入对象实现,这一点上 ajv 性能更好

  • 移除额外
  • 添加 defaults
  • 强制类型转换
  • coerceTypes=true|'array'
    • array 支持 x <-> [x]
const ajv = new Ajv({ removeAdditional: true, useDefaults: true, coerceTypes: 'array' });

const schema = {
type: 'object',
additionalProperties: false,
properties: {
foo: { type: 'array', items: { type: 'number' } },
bar: { type: 'boolean' },
num: { type: 'number' },
name: { type: 'string', default: 'wener' },
},
};

const data = { foo: '1', bar: 'false', rm: true, num: '10' };

const validate = ajv.compile(schema);

// true
console.log(validate(data));
// {foo: [1], bar: false, num: 10, name: "wener"}
console.log(data);