image.png
image.png
ajv是最快的json规则校验器。使用ajv的项目和公司非常之多。

基本使用

ajv怎么用,先分析下官网案例:

  1. import Ajv from "ajv"
  2. const ajv = new Ajv() // options can be passed, e.g. {allErrors: true}
  3. // json-schema数据
  4. const schema = {
  5. type: "object",
  6. properties: {
  7. foo: {type: "integer"},
  8. bar: {type: "string"}
  9. },
  10. required: ["foo"],
  11. additionalProperties: false,
  12. }
  13. // 等待校验的数据
  14. const data = {
  15. foo: 1,
  16. bar: "abc"
  17. }
  18. // validate函数对数据校验
  19. const validate = ajv.compile(schema)
  20. const valid = validate(data)
  21. if (!valid) console.log(validate.errors)

简单的看了上述流程,可以看到,使用ajv大致有三步:

  1. 结构化描述json的合规数据:json-schema;(json-schema就是用来描述json数据的json数据,是一种公共规范)
  2. ajv处理schema得到validate函数;
  3. 使用validate函数对后续数据进行校验;

    json-schema

    其实核心在于json-schema的定义规则。
    image.png
    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;

    1. {
    2. type: "object",
    3. properties: {
    4. foo: {type: "string"},
    5. bar: {
    6. type: "number",
    7. minimum: 2
    8. }
    9. }
    10. }
  • foo是必填属性且不能有别的属性(additionalProperties: false, 不能有foo、bar之外的其他属性) ```json { type: ‘object’, properties: {

    1. foo: {
    2. type: 'integer',
    3. },
    4. bar: {
    5. type: 'string',
    6. },

    }, required: [‘foo’], additionalProperties: false, }

  1. - 要求bar必须等于foo的值,利用const
  2. ```json
  3. {
  4. type: "object",
  5. properties: {
  6. foo: {type: "number"},
  7. bar: {const: {$data: "1/foo"}}
  8. }
  9. }
  • 定义一个数组,值必须在枚举中:

    1. {
    2. "type": "string",
    3. "enum": [
    4. "fanwenjie",
    5. "tecvan"
    6. ]
    7. }
  • 提供了若干复合校验指令,比如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: [], };

  1. <a name="Zqjqv"></a>
  2. #### ajv-format
  3. 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 />简单参考
  4. ```javascript
  5. const Ajv = require('ajv');
  6. const addFormats = require('ajv-formats');
  7. const ajv = new Ajv({ allErrors: true });
  8. addFormats(ajv);
  9. const schema = {
  10. type: 'object',
  11. properties: {
  12. email: {
  13. type: 'string',
  14. format: 'email',
  15. },
  16. },
  17. };
  18. // 执行compile后validate可以多次使用
  19. const validate = ajv.compile(schema);
  20. const data = {
  21. email: '1825203636@qq.com',
  22. };
  23. // 执行数据校验
  24. const valid = validate(data);
  25. if (!valid) {
  26. console.log(validate.errors);
  27. }

当然,除了内置的format校验规则之外,还可以自己写规则:

  1. ajv.addFormat("byte", {
  2. type: "number",
  3. validate: (x) => x >= 0 && x <= 255 && x % 1 == 0,
  4. })

还有一些其他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