JsonSchema的理解及实践demo

前言

JsonSchema是什么?

有什么特性

        优:

        限制:

关键概念理解

        声明方言:

        模式:

        关键字:

        标识符:

        有哪些标识符?        

         哪些关键字可以设置标识符?

        模式识别:

        $defs关键字:

        JSON指针

规范

        $schema:

        $id:

        类型关键字type:

        常用通用关键字:

        用于组合模式关键字:

        必要依赖关键字:

        模式依赖关键字:

        条件语句关键字:

如何代码中体现这些特性

能做些什么(适用场景)


前言

         在学习Mall-Cook低代码平台时第一次接触JsonSchema,get到利用JsonSchema可快速生成一个属性面板表单组件,对于开发一个业务组件简直是个利器。

        但对于JsonSchema的认知仅停留局限在有清晰的数据结构描述,数据格式的团队弱约束上,但其实JsonSchema的作用,可远不是弱约束(只是团队内部人员达成共识哪些字段需要,字段起名规则,字段值的约定),它可以通过一系列的关键字实现 强大的验证和强约束;同时也有丰富的数据类型支持;还有强大的拓展能力,跨语言能力;利用这些特性,我们可以实现像通过表单的rules一样对于我们的json数据有更加精细且强制的校验。

        本文将通过以下几点来进一步沉淀对于JsonSchema的理解,结合实际的demo实践进一步验证JsonSchema的强大能力。

JsonSchema是什么?

        描述json数据结构的声明式格式,本身就是一个json文件。

有什么特性

优:

        可简明的描述数据格式和结构,并能根据配置的关键字和对应的值,自行校验数据。这点很有效。

跨开发编程语言,他只是一种数据格式,可在各种环境中使用。

构建复杂模式  可达到  模式抽离,嵌套,复用效果,便于维护,逻辑结构更清晰。

限制:

        但jsonSchema本身就是一个json文件,数据之间的关联及逻辑关系这种语义化描述上有所限制,需要结合具体的开发编程语言来实现。

关键概念理解

声明方言:

        json schema的版本被称为方言。使用$schema关键字来约定,每个json schema文件都必须要有此配置,且位于根级别,嵌套模式下,也需要有自己的$schema配置,版本可以不一致。

模式:

        每一个json schema文件就是一个模式,模式中引用其他模式的情况被称为 复杂模式。没有标识符的模式被称为 匿名模式

关键字:

        这个就不用说啦,json schema就是通过一系列关键字来实现对于数据结构的描述。(如:type类型关键字,$schema方言关键字,properties属性对象关键字等)

标识符:

        一个模式引用其他模式时需要有一个标识符(其实就是路径引用)。

        有哪些标识符?

                URI/非相对URI:    全量地址,https://***.com/a/c#demo

                相对-URI引用:不包含http://**.com域名部分之后的内容,如 /a/c#demo,#/demo,

                URI-引用:全量地址,或者是相对-URI 

                绝对URI: 不包含锚点后的地址,https://***.com/a/c,https://***.com

        哪些关键字可以设置标识符?

                $id: 推荐设置绝对URI,作为模式的基础URI,模式的唯一标识符。对于此模式下引用

                        其他模式时,作为拼接引用基础路径很有用.(如:https://***.com#/a/c)

                $ref: 1.设置相对-URI,用来引用其他模式。(如:/d/e),常见于$defs中的捆绑模式;

                        2.设置带#的相对-URI

                                json指针。(如:https://***.com/a/c#/d/e),此种解析相当于引用                                 https://***.com/a/c 这个模式下   键d的值中键e的值(类似对象中键值访问) 

                                锚点。(如:https://***.com/a/c#d)需要配合$anchor使用,引用外部模式;

                                                (#d),需要配合$anchor使用,引用内部模式;

                                引用仅内部使用的模式。(如#/$defs/a)    

模式识别:

        一个模式a  引用其他模式b时  需要有一个标识符,当模式b被标识符引用时,就是模式b被识别的过程。

$defs关键字:

        一个模式只仅限于某个模式内部使用,可用$defs标记抽离为子模式,子模式的写法和一般模式写法一样。(简单可以理解为仅提供给函数内部使用  无需单独抽离 的对象。)

JSON指针

        JSON 指针描述了一个以斜线分隔的路径来遍历文档中对象中的键。参考上述的$ref中第2条。

规范

        json schema的规范标准修订过多次,目前最新版本是7,版本4被广泛使用。以下的demo以最新的版本为例,不同版本对不同标准的支持程度及差异,请参考官网差异

$schema:

        规定此文件为json-schema文件,且声明写入的json模式规范是哪个版本;

$id:

        模式唯一标识符

类型关键字type:

        限定接收的数据特定类型;

常用通用关键字:

        title:此模式的title

        description: 此模式的具体描述

        default: 一个默认值,不用于空值的占位填充,只是用来提示如何填写/使用此值。

        enum: 限定一组固定值的数据,每个元素唯一。固定枚举值很有用。

        const: 限定值是一个特定值

        readOnly:只读,通常用于接口api上下文

        writeOnly:只改,通常用于接口api put类型上下文

        $comment: 注释

用于组合模式关键字:

        在其他关键字的基础上叠加以下关键字,可实现  体现并约束一些复杂的模式  功能。无需 构建复杂模式那样  需要多个模式叠加实现。

        allOf: 值为数组,每个数组项都是一个模式,给定的数据 必须通过每个模式的校验

        anyOf: 值为数组,每个数组项都是一个模式,给定的数据  需要通过任意1个或者多个模式的验证

        oneOf: 值为数组,每个数组项都是一个模式,给定的数据 必须且只能通过其中1个模式的验证

        not:  值为对象,给定数据不能满足此模式,才算验证通过

必要依赖关键字:

        dependentRequired:{存在的key:['必须存在的key1','必须存在的key2']}

        上述依赖项不是双向的,如果想要双向的,需要同样上述格式反过来再写一遍。

模式依赖关键字:

        dependenciesSchemas:{

                存在的key:{

                        properties:{

                                '必须存在的key1':{

                                         type:'类型'

                                }

                        }

                }

        }

        和dependentRequired的作用是一样的,只不过这里依赖的是一个模式

条件语句关键字:

        以下 关键字允许基于一种模式来应用子模式(基于某些条件true/false来实现语义化的判断逻辑)

        if/then/else:

                 if为true时,then必须也为true,整个schema才能为true。

                  if为false时不关心then,以else返回的true/false作为整个schema的校验结果。

构建复杂模式:

        json schema可以像组件/方法一样,可以将公共的验证模式提取出来,不同模式相互引用,从而达到复用,组合成更符合业务场景的复杂模式。一般是通过 $id,$ref,$defs,$anchor这几个关键字来组合实现。

        

如何代码中体现这些特性

        工欲善其事必先利其器,先推荐几个工具,大家可快速的在线验证自己的schema内容是否书写正确,同时可快速验证值是否符合schema的要求;

在线js转化为json工具

在线json转化为json schema工具

json schema lint 在线验证工具

JSON Schema Validator 在线验证工具 (如果要验证$ref模式相关引用的场景,推荐使用此工具,上面那个工具不支持此场景)

        以上所有的规范具体的代码实践请参考

jsonSchema 规范代码仓icon-default.png?t=O83Ahttps://github.com/zhangpanjun/jsonSchema

        (每个demo都包含2个文件,一个是盛放schema的json文件,一个是盛放数据的js文件,可将schema和js的值分别贴到  ‘在线json schema验证工具’ 的左右两边,即可实时验证。)

能做些什么(适用场景)

根据json数据格式快速生成动态form表单;

输入数据的快速验证,ajv是json schema践行者之一的插件,ajv插件被广泛应用在代码的规范插件中,例如:eslint 。

另外,使用npm下载下来的很多插件中都有ajv对于插件内部数据格式的验证的身影。(比如webpack)

拓展插件

        关于json schema的践行者有很多第三方插件,这些插件既可以支持不同json结构草案,还可以支持自定义一些内容,同时提供更加方便的api来快速验证。

        ajv

        json-schema-benchmark

        jsck

        z-schema 基准

        themis 基准

这里推荐ajv插件,具体的实践demo请移步代码仓   GitHub - zhangpanjun/ajv-demos: Ajv 可以将 JSON 结构转换为超快速的校验函数,实现对json schema规则下的json输入数据快;本项目是基于ajv插件实现的一些基础用法demos

相关链接

JSON Schema 规范(中文版) - JSON Schema 规范(中文版)

为什么使用 AJV | Ajv 中文网

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值