前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Ajv】JSON Schema Validator

【Ajv】JSON Schema Validator

作者头像
前端小鑫同学
发布2022-12-26 12:23:22
2.1K0
发布2022-12-26 12:23:22
举报
文章被收录于专栏:小鑫同学编程历险记

JSON Schema:

     JSON Schema是一份用来注释和验证JSON文档开源草案,通过JSON Schema可以描述现有的数据格式,可以完成数据的自动化测试,可以有效保障数据提交的质量。

Ajv介绍及使用:

     在JavaScript领域,Ajv 提供了完整的符合 JSON Schema 规范的数据校验。Ajv 的赞助商有moz://aMicrosoft等,使用Ajv的开源项目也非常多,如:ESLintwebpack等,并且在NodeJs浏览器桌面应用程序微信小程序等平台均有应用。

image.png
image.png

上手使用:

使用步骤说明:
  1. 安装、导入、实例化:
代码语言:javascript
复制
// npm i ajv
const Ajv = require('ajv');
const ajv = new Ajv();
复制代码
  1. 定义schema;
  2. 执行compile生成validate函数;
  3. 执行validate函数检查数据。
schema定义说明:
  1. type设置为object表示目标JSON文档是一个对象;
  2. properties设置这个对象的属性包括foo、bar并分别指明其类型;
  3. required通过列表的形式限制foo为必填项;
  4. additionalProperties设置为false表示仅能包已声明的属性**。**
常见类型的定义:
  1. 定义对象类型:
代码语言:javascript
复制
const schema = {
  type: 'object',
  properties: {
    attribute1,
    attribute2,
    ...
  },
  required: ['attribute1'], // 必填属性
  additionalProperties: false, // 禁止多余属性
}
复制代码
  1. 定义字符串类型:
代码语言:javascript
复制
const schema = {
  type: 'string',
  minLength: 10, // 最小长度需满足10
}
复制代码
  1. 定义数字类型:
代码语言:javascript
复制
const schema = { type: 'number' }
复制代码
  1. 定义布尔类型:
代码语言:javascript
复制
const schema = { type: 'boolean' }
复制代码
  1. 定义数组/类数组类型:
代码语言:javascript
复制
const schema = {
  type: 'array',
  items: {
    type: 'string' // 定义数组的每一项均为字符串类型
  }
}
// and
const schema = {
  type: 'array',
  items: [	// 定义数据包含两个元素,元素1位数字类型,元素2为字符串类型
    {
      type: 'number'
    },{
      type: 'string'
    }
  ]
}
复制代码
案例代码:

运行下面的代码会同时得到三条违反规则的提示:

  1. fn1:must NOT have additional properties,不需要额外的属性出现。
  2. /foo:must be integer,仅支持整数。
  3. /bar:must be string,仅支持字符串。
代码语言:javascript
复制
const Ajv = require('ajv');
const ajv = new Ajv({ allErrors: true });

const schema = {
    type: 'object',
    properties: {
        foo: {
            type: 'integer',
        },
        bar: {
            type: 'string',
        },
    },
    required: ['foo'],
    additionalProperties: false,
};

// 执行compile后validate可以多次使用
const validate = ajv.compile(schema);

const data = {
    foo: 'foo',
    bar: 200,
    fn1: 'fn1',
};

// 执行数据校验
const valid = validate(data);
if (!valid) {
    console.log(validate.errors);
}
复制代码

Format关键字:

使用步骤说明:

从ajv7开始由ajv-formats提供属性的format工作。

  1. 安装、导入、初始化:
代码语言:javascript
复制
// npm i ajv-formats
const addFormats = require('ajv-formats');

// ajv 实例化后添加
addFormats(ajv);
复制代码
  1. 内置的format关键字有:date、time、date-time、uri、url、email等。
  2. format仅作用于类型为string或number的属性。
自定义Format:
  1. 使用addFormat增加一个通过正则验证完成的Format:
代码语言:javascript
复制
ajv.addFormat("identifier", /^a-z\$_[a-zA-Z$_0-9]*$/)
复制代码
  1. 仅作用在number类型上的Format:
代码语言:javascript
复制
ajv.addFormat("byte", {
  type: "number",
  validate: (x) => x >= 0 && x <= 255 && x % 1 == 0,
})
复制代码
案例代码:
代码语言: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);
}
复制代码

自定义关键字:

     自定义关键字可以弥补预定义字段无法完成的验证场景,简化程序结构。 实现range关键字:

代码语言:javascript
复制
const schema = {
  type: "object",
  properties: {
    username: { type: "string" },
    password: { type: "string" },
    age: { type: "number" },
    // 验证邮箱的长度在 5~25 个字符之间
    email: { type: "string", format: "email", range: [5, 25] },
  },
  required: ["username", "password"],
  additionalProperties: false,
};
复制代码
用“validate”函数定义关键字:

     通过addKeyword函数新增一个使用validate定义的关键字校验,满足在执行ajv.validate时邮箱的字段长度符合一定的区间。

代码语言:javascript
复制
ajv.addKeyword({
  keyword: "range",
  validate: (schema, data) => {
    if (typeof schema == "object" && schema !== null && data) {
      const minLength = schema[0];
      const maxLength = schema[1];
      if (data.length >= minLength && data.length <= maxLength) {
        return true;
      }
    }
    return false;
  },
  errors: false,
});
复制代码
用"compile"函数定义关键字:

ajv.compile阶段会对关键字的类型进行校验,保证关键字的正确使用。

代码语言:javascript
复制
ajv.addKeyword({
  keyword: "range",
  compile([minLength, maxLength], parentSchema) {
    // parentSchema:读取 schema 中更多的信息来做判断
    return (data) => {
      if (data.length >= minLength && data.length <= maxLength) {
        return true;
      }
      return false;
    };
  },
  // 规范自定义关键字的类型
  metaSchema: {
    type: "array",
    items: [{ type: "number" }, { type: "number" }],
    minItems: 2,
    maxItems: 2,
    additionalItems: false,
  },
  errors: false,
});
复制代码
用“宏”函数定义关键字:

     通过定义macro类型关键字可以很方便的通过一个关键字来为 schema 定义批量增加数据校验。

代码语言:javascript
复制
ajv.addKeyword({
  keyword: "range",
  macro: ([minLength, maxLength], parentSchema) => {
    return { minLength, maxLength };
  },
  errors: false,
});
复制代码

多语言支持:

使用步骤说明:
  1. 安装、导入、初始化:
代码语言:javascript
复制
// npm i ajv-i18n
const localize = require("ajv-i18n");

// 校验未通过后对错误内容进行转换处理
localize.zh(validate.errors);
复制代码
案例代码:
代码语言:javascript
复制
const Ajv = require("ajv");
const addFormats = require("ajv-formats");
const localize = require("ajv-i18n");
const ajv = new Ajv();
addFormats(ajv);

ajv.addKeyword({
  keyword: "range",
  macro: ([minLength, maxLength], parentSchema) => {
    return { minLength, maxLength };
  },
  errors: false,
});

const schema = {
  type: "object",
  properties: {
    username: { type: "string" },
    password: { type: "string" },
    age: { type: "number" },
    email: { type: "string", format: "email", range: [5, 15] },
  },
  required: ["username", "password"],
  additionalProperties: false,
};

const data = {
  username: "xiaoxin",
  password: "xiaoxin",
  email: "1825203636@qq.com",
};

const validate = ajv.compile(schema);
const valid = validate(data);

if (!valid) {
  localize.zh(validate.errors);
  console.log(validate.errors);
}
复制代码
image.png
image.png

自定义错误信息:

使用步骤说明:
  1. 安装、导入、配置:
代码语言:javascript
复制
// npm i ajv-errors

// ajv实例化后执行
require("ajv-errors")(ajv);

// 配置字段的新属性errorMessage,针对类型和其他关键字做不同的错误提示:
errorMessage: {
    type: "必须是字符串",
    minLength: "输入的用户名太短了",
}
复制代码
  1. i18 库存与ajv-errors似乎需要特殊处理;
案例代码:
代码语言:javascript
复制
const Ajv = require("ajv");
const ajv = new Ajv({ allErrors: true });
require("ajv-errors")(ajv);

ajv.addKeyword({
  keyword: "range",
  macro: ([minLength, maxLength], parentSchema) => {
    return { minLength, maxLength };
  },
  errors: false,
});

const schema = {
  type: "object",
  properties: {
    username: {
      type: "string",
      minLength: 10,
      errorMessage: {
        type: "必须是字符串",
        minLength: "输入的用户名太短了",
      },
    },
    password: { type: "string" },
    age: { type: "number" },
    email: { type: "string", range: [5, 25] },
  },
  required: ["username", "password"],
  additionalProperties: false,
};

const data = {
  username: "xiaoxin",
  password: "xiaoxin",
  email: "1825203636@qq.com",
};

const validate = ajv.compile(schema);
const valid = validate(data);

if (!valid) {
  console.log(validate.errors);
}
复制代码
image.png
image.png
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JSON Schema:
  • Ajv介绍及使用:
    • 上手使用:
      • 使用步骤说明:
      • schema定义说明:
      • 常见类型的定义:
      • 案例代码:
    • Format关键字:
      • 使用步骤说明:
      • 自定义Format:
      • 案例代码:
    • 自定义关键字:
      • 用“validate”函数定义关键字:
      • 用"compile"函数定义关键字:
      • 用“宏”函数定义关键字:
    • 多语言支持:
      • 使用步骤说明:
      • 案例代码:
    • 自定义错误信息:
      • 使用步骤说明:
      • 案例代码:
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档