logo
登录 / 注册

JSON Schema入门和应用

头像
叶俏锋
2022-03-04 · 前端负责人

file

本文首发于:github.com/bigo-fronte… 欢迎关注、转载。

JSON Schema入门和应用

何为JSON Schema?

JSON数据格式对于web开发者都为所熟悉,在平时的开发中离不开它,例如前后端数据传输格式,webpack配置文件,对象序列化等实际应用场景,通常都以JSON格式定义和储存。它以简洁易懂的结构、体积小的优点得以在各类编程语言中广泛流行。

那么什么是JSON Schema?
JSON Schema其实是对json数据格式的描述和规范,是对JSON格式一种约束,更明确地定义数据的类型和结构。伴随着JSON被创造出来,JSON Schema的诞生是必然的,类似其他数据格式YAML,也会创造YAML Schema的标准来进行规范,并使用这个规范来校验格式。这就好比有了Javascript,自然就会有Typescript,开发者更倾向于使用工具替代人为来进行约束,校验,使开发效率和开发质量大大加强。

掌握使用

举个简单的例子,你便清楚JSON Schema的使用

这里有两个对象a,b,唯一的区别是对象里的属性类型不同,当你想指定对象属性的类型时,假若你只想要字符串类型,那么可以使用JSON Schema来进行定义

{   "type": "object",   "properties": {     "title": {       "type": "string"     }   } } 复制代码

// right var a = {   title: '123' } // error var b = {   title: 123 } 复制代码

上面是最简洁的JSON Schema对象定义,从中我们可以得知定义的变量类型是对象,而这个变量对象里具有title属性,title属性的类型是string类型。好了,到这里你已经掌握了JSON Schema使用,是不是好简单🐕。

当然,JSON Schema既然是一套标准和规范,那么就会有好多语义需要理解,下面说说常见用法

数据类型

在JSON Schema中使用最多的是type关键字,它包含了JSON格式的基本类型

类型描述
string字符串型,双引号包裹的 Unicode 字符和反斜杠转义字符
number数字型,包括整型(int)和浮点数型(float)
boolean布尔型,true 或 false
object对象型,无序的键:值对集合
array数组型,有序的值序列
null空型

关键字

以Object类型为例,列举在JSON Schma所经常用到的关键字

示例:

{   "$schema": "http://json-schema.org/draft-04/schema#",   "$id": "https://example.com/schemas/person",   "title": "base info",   "description": "base information about person",   "type": "object",   "required": ["name", "age", "phone"],   "definitions": {     "name": {       "type": "string",       "minLength": 1,       "maxLength": 10     }   },   "properties": {     "name": {       "type": "string",       "minLength": 1,       "maxLength": 10     },     "age": {       "type": "number",       "minimum": 18,       "exclusiveMinimum": true,       "maximum": 65,       "exclusiveMaximum": true     },     "phone": {       "type": "string",       "pattern": "^1\\d{10}$"     },     "parents": {       "type": "array",       "items": [{ "$ref": "#/definitions/name" }],       "minItems": 1,       "maxItems": 2,       "uniqueItems": true     },     "address": {       "type": "object",       "properties": {         "city": {           "type": "string",           "enum": ["guangzhou", "beijing"]         }       }     }   } } 复制代码

关键字描述
$schema声明此json片段属于JSON Schema,并遵循所声明的JSON Schema版本规范
$id为JSON Schema声明一个统一资源标识符,使解析$ref时能够引用片段
title为JSON Schema文件提供标题
description为JSON Schema文件提供描述信息
definitions声明子schema,使解析$ref能够引用片段
$ref引用JSON Schema片段
required定义对象类型properties所声明的字段是否必须,值必须是数组,数组中的元素必须是字符串类型且唯一
type定义元素的类型
properties定义对象类型里的属性(键值对),每个字段的值都是一个有效的schema片段,用来限制每个字段的格式
minimum约束取值范围,标识取值范围应该大于或等于minimum
exclusiveMinimum假若minimum或exclusiveMinimum同时存在,且exclusiveMinimum为true,则取值范围大于minimum
maximum约束取值范围,标识取值范围应该小于或等于maximum
exclusiveMaximum假若maximum或exclusiveMaximum同时存在,且exclusiveMaximum为true,则取值范围小于maximum
minLength字符串类型数据的最小长度
maxLength字符串类型数据的最大长度
pattern使用正则表达式约束字符串类型数据
items用来定义数组类型的子元素,值必须为数组,且是一个有效的schema片段
minItems定义数组类型大小的最小长度
maxItems定义数组类型大小的最大长度
uniqueItems定义数组类型子元素是否必须唯一
enum用来限制值的范围,值必须在enum所指定的集合里面

以上是比较常用到的关键字,还有一些其他的关键字可以阅读官方文档进行深入地了解和使用

Understanding JSON Schema

进阶使用:

正则属性

提供patternProperties关键字,对属性字段名提供正则校验

{   "type": "object",   "patternProperties": {     "^S_": { "type": "string" },     "^I_": { "type": "integer" }   } } 复制代码

// right "{ "S_25": "This is a string" }" // right { "I_0": 42 } 复制代码

// error S_开头的字段名的值必须为字符串类型 { "S_0": 42 } // error I_开头的字段名的值必须为数值类型 { "I_42": "This is a string" } 复制代码

组合sechma

JSON Sechma提供一些关键字来讲多个子schema片段组合在一起,类似布尔算符AND, OR, XOR, 和 NOT,通过布尔逻辑来验证

关键字描述
allOf相当于AND布尔算符,必须满足所有的子schema校验
anyOf相当于OR布尔算符,必须满足任意子schema校验
oneOf相当于XOR布尔算符,必须满足其中一个子schema校验
not相当于NOT布尔算符,必须都不满足所有的子schema校验

allOf关键字为例:

必须要满足符合字符串类型且最大长度为5的值

{   "allOf": [     { "type": "string" },     { "maxLength": 5 }   ] } 复制代码

// right "short"  复制代码

// error 字符长度超出5 "too long"  复制代码

条件sechma

可以使用if,then,else关键字实现条件逻辑判断,当符合if子schema条件,则对then的子schema条件进行校验,若if子schema条件不通过,则走else子schema条件校验

{   "type": "object",   "properties": {     "street_address": {       "type": "string"     },     "country": {       "default": "United States of America",       "enum": ["United States of America", "Canada"]     }   },   "if": {     "properties": { "country": { "const": "United States of America" } }   },   "then": {     "properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }   },   "else": {     "properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }   } } 复制代码

// right // if的schema验证通过,则校验then的schema,20500 符合 /[0-9]{5}(-[0-9]{4})?/ 正则表达式 {   "street_address": "1600 Pennsylvania Avenue NW",   "country": "United States of America",   "postal_code": "20500" } 复制代码

// error // if的schema验证不通过,则校验else的schema,10000 不符合 /[A-Z][0-9][A-Z] [0-9][A-Z][0-9]/ 正则表达式 {   "street_address": "24 Sussex Drive",   "country": "Canada",   "postal_code": "10000" } 复制代码

递归

使用$ref关键字引用自己的子schema片段,实现递归模式,可以用于树形结构的描述

{   "$schema": "http://json-schema.org/draft-04/schema#",   "title": "$ref递归调用",   "definitions": {     "node": {       "type": "object",       "properties": {         "children": {           "type": "array",           "items": {             "$ref": "#/definitions/node"           }         }       }     }   },   "type": "object",   "properties": {     "tree": {       "$ref": "#/definitions/node"     }   } } 复制代码

以下的JSON结构才能在上述的JSON Schema校验通过

{   "tree": {     "children": [       {         "children": [           {             "children": []           }         ]       }     ]   } } 复制代码

应用

JSON Schema规范了JSON格式,使JSON的解析控制在一定的范围了,在JSON输入到输出等过程中添加Schema协议的校验,减少了代码程序出错的几率,一定程度上保证了代码的质量。
JSON Schema在公司的内部项目上也有应用,例如raptor活动运营平台JSON Schema可视化组件编辑器,pear配置管理平台使用JSON Schema生成输入表单,在amis开发中通过json配置中台页面等等。可见,JSON Schema在代码开发过程中发挥不可忽视的作用,我们应该加以理解并应用JSON Schema,下面归纳一下JSON Schema一些用途。

1、生成JSON格式可读文档

使用过typescript都应该了解静态类型的好处,代码包含了类型接口声明,相当于文档注释,使代码一目了然,提高了可读性。我们可以基于现有的JSON来生成JSON Schema,快速生成JSON格式规范,相当于一份可读文档,减少了团队之间的沟通理解成本。

通过JSON转换JSON Schema在线工具:
www.jsonschema.net/

2、提供更为准确可靠的mock数据

基于JSON Schema提供多种校验约束条件,可以使用它原生的能力来生成更为准确可靠的mock数据

使用JSON Schema生成mock数据在线工具:
json-schema-faker.js.org/

3、数据校验

基于JSON Schema提供多种校验约束条件,可以定义数据的校验规则,通过JSON Schema进行数据校验,多用于接口请求参数校验,表单校验,和数据校验自动化测试上

JSON Schema校验工具:Ajv

4、基于JSON Schema配置文件渲染UI组件

1

借助vue、react框架组件化理念以及动态渲染组件能力,涌现了许多基于JSON Schema配置文件渲染表单或者组件的库,有效解决通用性组件大量重复使用的场景。通过JSON配置组件乃至页面,能够使代码转化为文件,使数据得以导入导出,便于迁移储存。另外也可以开发可视化编辑器,通过拖拽交互,生成JSON文件,降低开发使用难度。基于这一系列的方案,使开发效率大大提升和降低后续的代码维护。

在vue框架下,vue-json-schema-form提供了表单组件生成工具

vue-json-schema-form 基于JSON Schema的关键字type所定义的类型来渲染对应表单组件,并适配了第三方的UI库

主要架构:

3

渲染流程:

2

参考资料:

Understanding JSON Schema
vue-json-schema-form


欢迎大家留言讨论,祝工作顺利、生活愉快!


我是bigo前端,下期见。


JSON Schema入门和应用脉脉
阅读 27
声明:本文内容由脉脉用户自发贡献,部分内容可能整编自互联网,版权归原作者所有,脉脉不拥有其著作权,亦不承担相应法律责任。如果您发现有涉嫌抄袭的内容,请发邮件至maimai@taou.com,一经查实,将立刻删除涉嫌侵权内容。
头像
我来说几句...
脉脉App内打开