ajv是最快的json规则校验器。使用ajv的项目和公司非常之多。
基本使用
ajv怎么用,先分析下官网案例:
import Ajv from "ajv"
const ajv = new Ajv() // options can be passed, e.g. {allErrors: true}
// json-schema数据
const schema = {
type: "object",
properties: {
foo: {type: "integer"},
bar: {type: "string"}
},
required: ["foo"],
additionalProperties: false,
}
// 等待校验的数据
const data = {
foo: 1,
bar: "abc"
}
// validate函数对数据校验
const validate = ajv.compile(schema)
const valid = validate(data)
if (!valid) console.log(validate.errors)
简单的看了上述流程,可以看到,使用ajv大致有三步:
- 结构化描述json的合规数据:json-schema;(json-schema就是用来描述json数据的json数据,是一种公共规范)
- ajv处理schema得到validate函数;
- 使用validate函数对后续数据进行校验;
json-schema
其实核心在于json-schema的定义规则。
understanding-json-schema
json-schema 是一种以 JSON 格式描述数据结构的 公共规范,使用时至少需要提供 type 参数
json-schema支持七种基本数据类型。
- number:数值型,支持整数、浮点数,支持如下校验规则:
- maximum/minimum:属性值必须大于等于 minimum ,且小于等于 maximum;
- exclusiveMaximum/exclusiveMinimum:属性值必须大于 exclusiveMinimum ,且小于 exclusiveMinimum;
- multipleOf:属性值必须为 multipleOf 的整数倍,例如对于 multipleOf = 5,则 10/20/5 均符合预期,但 8/9/1 等不符合预期。
- interger:整数型,与 number 类似,也支持上面介绍的 maximum 等校验规则;
- string:字符串型,支持如下校验规则:
- maxLength/minLength:限定字符串的最大长度、最小长度;
- pattern:以正则表达式方式限定字符串内容;
- format:声明字符串内容格式,默认支持 date/ipv4/regex/uuid 等格式。
- boolean:bool 值;
- array:数组型,支持如下校验属性:
- maxItems/minItems:限定数组的最多、最少的元素数量;
- uniqueItems:限定数组元素是否必须唯一,不可重复;
- items:声明数组项的 Schema 描述,数组项内可复用 JSON-Schema 的任意规则,从而形成嵌套定义结构;
- null:空值,常用于复合 type 类型,如 type = [‘object’, ‘null’] 支持传入对象结构或 null 值;
- object:对象结构,这是一个复杂结构,支持如下校验属性:
- maxProperties / minProperties:限定对象支持的最多、最少属性数量;
- required:声明哪些属性不可为空,例如 required = [‘name’, ‘age’] 时,传入的值必须至少提供 name/age 属性;
- properties:定义特定属性的 Schema 描述,与 array 的 items 属性类似,支持嵌套规则,例如:
举例:
定义一个对象有两个属性foo和bar,foo的类型是string,bar的类型是number且要求大于等于2;
{
type: "object",
properties: {
foo: {type: "string"},
bar: {
type: "number",
minimum: 2
}
}
}
foo是必填属性且不能有别的属性(additionalProperties: false, 不能有foo、bar之外的其他属性) ```json { type: ‘object’, properties: {
foo: {
type: 'integer',
},
bar: {
type: 'string',
},
}, required: [‘foo’], additionalProperties: false, }
- 要求bar必须等于foo的值,利用const
```json
{
type: "object",
properties: {
foo: {type: "number"},
bar: {const: {$data: "1/foo"}}
}
}
定义一个数组,值必须在枚举中:
{
"type": "string",
"enum": [
"fanwenjie",
"tecvan"
]
}
提供了若干复合校验指令,比如not、anyOf、oneOf、allOf、if-then-else等,更多更复杂的校验规则,初次接触,先知道有这么回事,如有需要参考:复合校验指令
ajv-keywords
json-schema不支持 js 里复杂数据类型的具体类型,比如 function, date …,因而需要引入 ajv-keywords 进行额外补充。 ```javascript import Ajv from “ajv”; import AjvKeywords from “ajv-keywords”;
const ajv = new Ajv();
// 除了 type 定义类型外,还可以通过 typeof,instanceof AjvKeywords(ajv, [“typeof”, “instanceof”]);
// 规定校验类型 const schema = { type: “object”, properties: { // 属性 get: { type: “object”, // 类型 properties: { url: { type: “string”, }, method: { type: “string”, }, }, required: [“url”], // 必须包含 url 属性 }, getMethod: { instanceof: “Function”, // typeof 类似,只是支持的类型不同 }, list: { instanceof: [“Function”, “Array”], }, }, };
const data = { get: { url: “http://localhost:8080/get“, }, getMethod() {}, list: [], };
<a name="Zqjqv"></a>
#### ajv-format
ajv-formats提供属性的format工作,内置的format关键字有:date、time、date-time、uri、url、email等,format仅作用于类型为string或number的属性。<br />具体默认规则参考:[ajv-formats](https://github.com/ajv-validator/ajv-formats),是很多的<br />简单参考
```javascript
const Ajv = require('ajv');
const addFormats = require('ajv-formats');
const ajv = new Ajv({ allErrors: true });
addFormats(ajv);
const schema = {
type: 'object',
properties: {
email: {
type: 'string',
format: 'email',
},
},
};
// 执行compile后validate可以多次使用
const validate = ajv.compile(schema);
const data = {
email: '1825203636@qq.com',
};
// 执行数据校验
const valid = validate(data);
if (!valid) {
console.log(validate.errors);
}
当然,除了内置的format校验规则之外,还可以自己写规则:
ajv.addFormat("byte", {
type: "number",
validate: (x) => x >= 0 && x <= 255 && x % 1 == 0,
})
还有一些其他ajv相关的库,比如ajv-error、ajv- i8n、ajv-async等,需要参考:https://github.com/orgs/ajv-validator/repositories
参考:
ajv官方github
ajv的中文文档
【Ajv】JSON Schema Validator - 掘金
使用ajv校验json-schema数据格式 - 掘金
掘金小册-webpack-chapter20