一. 概念和用途
JSON Schema指的是数据交换中的一种虚拟的“合同”。
JSON验证器负责验证语法错误,JSON Schema负责提供一致性检验。
JSON Schema可以解决下列有关一致性验证的问题。
1、 值的数据类型是否正确:可以具体规定一个值是数字、字符串等类型;
2、 是否包含所需的数据:可以规定哪些数据是需要的,哪些是不需要的;
3、 值的形式是不是我需要的:可以指定范围、最小值和最大值。
特性和用途:
-
用于描述数据结构
在描述 JSON 数据时,如果数据本身的复杂度很高,高到三维四维,普通的标签函数已经无法表示这种层级结构了,而 JSON Schema 利用 object 和 array 字段类型的反复嵌套,可以规避掉这个缺陷。
当然,除了键值等基本信息,规范层面还提供了丰富的关键词支持,如果想通过自定义扩展字段,解决特定场景的业务需求,也是非常方便的。 -
用于构建人机可读的文档
计算机领域有个概念叫做自描述。所谓自描述,可以理解为:文档本身包含了自身与其他文档交互相关的描述信息,不需要其他的配置文件或者额外信息来描述。
而 JSON Schema 就是自描述的,它本身就是一份很完善的说明文档,字段的含义说明、该如何取值、格式的要求等都清晰明了。 -
用于生成模拟数据
通过标签函数生成模拟数据,只能解决基本的格式要求。比如 string 类型的字段,模拟出来的数据,无非是一个随机字符串。
但在 JSON Schema 中,由于字段的描述不仅仅是类型,更多的约束条件,可以确保模拟数据更接近于真实数据。 -
用于校验数据,实现自动化测试
接口数据的校验工作,往往依赖于测试代码逻辑和用例。如果用 JSON Schema 描述一个数据接口,就不需要再编写测试代码了,所有的逻辑都可以移植到 JSON Schema 中维护。配合 jsv、tv4 等二方校验工具,接口测试可以真正自动化。
二. 基本用法
2.1 启动架构
声明jsonschema:
$schema
架构关键字,指出此架构是根据标准的特定草稿编写的。
例如:"$schema": "http://json-schema.org/draft-07/schema#"
$id
架构关键字,定义模式的URI,并解析模式中其他URI引用的基URI。
例如: "$id": "http://example.com/product.schema.json"
title
和 description
关键字是描述性的,并不对数据具有约束作用,只是用来对文档作补充说明
type
验证关键字定义我们的JSON数据的第一个约束,在这种情况下,它必须是一个JSON对象。
启动架构举例:
{
"$schema": "[http://json-schema.org/draft-07/schema#](http://json-schema.org/draft-07/schema#)",
"$id": "[http://example.com/product.schema.json](http://example.com/product.schema.json)",
"title": "Product",
"description": "A product in the catalog",
"type": "object"
}
2.2 定义属性
properties
用于指定schema的参数,定义各个键和它们的值类型
type
关键字
{ "type": "string" }
当 type 为 object
类型时,properties
关键字是必需的
当 type 为 array
类型时,items
关键字是必需的。
type关键字 | 指定对象或属性的类型 |
---|---|
string | 字符串 |
number | 数字 |
integer | 整型 |
boolean | 布尔值 |
object | 对象 |
array | 列 |
array (with “uniqueItems”:true) | |
null | 空 |
any | 任意 |
title
关键字
标题,可省略
description
关键字
注释含义,可省略
required
关键字是一个字符串数组,验证必需包含的键。
exclusiveMinimum
关键字
该关键字的值为排除值。
例如:
"exclusiveMinimum": 0
代表必须是0以外的值
minimum
关键字
“minimum”的值必须是一个数字,表示数字实例的包含下限。
如果实例是数字,则仅当实例大于或等于“最小”时,此关键字才会生效。
maximum
关键字
“maximum”的值必须是一个数字,表示数字实例的包含上限。
如果实例是数字,则仅当实例小于或等于“最大”时,此关键字才会生效。
minItems
关键字
修饰array的条目数
此关键字的值必须是非负整数。
如果数组实例的大小大于或等于此关键字的值,则该实例对“minItems”有效。
省略此关键字的行为与值0相同。
maxItems
关键字
此关键字的值必须是非负整数。
如果数组实例的大小小于或等于此关键字的值,则该实例对“maxItems”有效。
uniqueItems
关键字
指出阵列中所有的项目必须是相对唯一的
id 的取值一定是唯一的,就像 css 中的 id 一样在当前文档中是不可重复的
描述地址信息或位置信息
空对象{}
可以描述和校验任意形式的json数据
2.3 架构外的引用
可在schema内部引用另外一个schema来合并验证
目的:重用,可读性和可维护性
ref
关键字
例如:
"warehouseLocation": {
"description": "Coordinates of the warehouse where the product is located.",
"$ref": "[https://example.com/geographical-location.schema.json](https://example.com/geographical-location.schema.json)"
}
ref
的值为被引用的schema的$id
2.4 架构内的引用
可在schema内部引用另外一个schema来合并验证
definitions
和ref
关键字
例如:
{
...
"vegetables": {
"type": "array",
"items": { "$ref": "#/definitions/veggie" }
}
},
"definitions": {
"veggie": {
"type": "object",
"required": [ "veggieName", "veggieLike" ],
"properties": {
"veggieName": {
"type": "string",
"description": "The name of the vegetable."
},
"veggieLike": {
"type": "boolean",
"description": "Do I like this vegetable?"
}
...
三. 语法词典
3.1 适用性
以下几个关键字用于确定将哪些子模式应用于数组项,对象属性值和对象属性名称:
items
properties
additionalItems
contains
patternProperties
additionalProperties
propertyNames
“contains”
关键字仅要求其子模式对至少一个子实例有效,而其他关键字要求所有子模式对其应用的所有子实例都有效。
3.1.1 关键字独立
验证关键字通常独立运行,而不会影响彼此的结果。但以下有几个例外:
“additionalProperties”
,其行为是根据“properties”
和“patternProperties”
定义的; 和
“additionalItems”
,其行为是根据“items”定义的。
3.2 验证关键字
3.2.1 任何实例类型的验证关键字
type
该关键字的值必须是字符串或数组。如果它是一个数组,那么数组的元素必须是字符串,并且必须是唯一的。
字符串可取值:
“null”,“boolean”,“object”,“array”,“number”或“string”
或”integer”,它匹配任意的整数
enum
该关键字的值必须是一个数组。这个数组应该至少有一个元素。数组中的元素应该是唯一的。
数组中的元素可以是任何值,包括null。
const
此关键字的值可以是任何类型,包括null。
3.2.2 数字实例的验证关键字(数字和整数)
multipleOf
仅当被这个关键词的值除以之后的结果是一个整数时,这个数字的实例才是有效的。
maximum
“maximum”的值必须是一个数字,表示数字实例的包含上限。
如果实例是数字,则仅当实例小于或等于“最大”时,此关键字才会生效。
exclusiveMaximum
“exclusiveMaximum”的值必须是数字,表示数字实例的独占上限。
如果实例是数字,则实例仅在其值严格小于(不等于)“exclusiveMaximum”时才有效。
minimum
“minimum”的值必须是一个数字,表示数字实例的包含下限。
如果实例是数字,则仅当实例大于或等于“最小”时,此关键字才会生效。
exclusiveMinimum
“exclusiveMinimum”的值必须是数字,表示数字实例的独占下限。
如果实例是数字,则实例仅在其值严格大于(不等于)“exclusiveMinimum”时才有效。
3.2.3 字符串的验证关键字
maxLength
此关键字的值必须是非负整数。
如果字符串实例的长度小于或等于此关键字的值,则该字符串实例对此关键字有效。
minLength
此关键字的值必须是非负整数。
如果字符串实例的长度大于或等于此关键字的值,则该字符串实例对此关键字有效。
省略此关键字的行为与值0相同。
pattern
该关键字的值必须是一个字符串。根据ECMA 262正则表达式方言,该字符串应该是有效的正则表达式。
如果正则表达式与实例成功匹配,则认为字符串实例有效。
3.2.4 Arrays 数组的验证关键字
items
“items”的值必须是有效的JSON格式或有效的JSON数组。
此关键字确定子实例如何验证数组,而不直接验证直接实例本身。
如果“items”是一个json对象,则如果阵列中的所有元素都成功验证该schema,则验证成功。
如果“items”是一个json数组,则如果实例的每个元素都针对相同位置的schema进行验证(如果有),则验证成功。
省略此关键字与空schema具有相同的行为。
additionalItems
“additionalItems”的值必须是有效的JSON格式
此关键字确定子实例如何验证数组,而不直接验证直接实例本身。
如果“items”是json数组,则如果位置大于“items”的位置的每个实例元素都对“additionalItems”进行验证,则验证成功。
否则,必须忽略“additionalItems”,因为“items”模式(可能是空模式的默认值)应用于所有元素。
省略此关键字与空schema具有相同的行为。
maxItems
此关键字的值必须是非负整数。
如果数组实例的大小小于或等于此关键字的值,则该实例对“maxItems”有效。
minItems
此关键字的值必须是非负整数。
如果数组实例的大小大于或等于此关键字的值,则该实例对“minItems”有效。
省略此关键字的行为与值0相同。
uniqueItems
(唯一性校验)
该关键字的值必须是布尔值。
如果此关键字的布尔值为false,则实例将成功验证。如果它具有布尔值true,则实例在其所有元素都是唯一的情况下成功验证。
省略此关键字的行为与false值相同。
contains
此关键字的值必须是有效的JSON格式。
如果至少有一个元素对给定的模式有效,则数组实例对“contains”有效。
3.2.5 Objects 对象的验证关键字
maxProperties
此关键字的值必须是非负整数。
如果对象实例的属性数小于或等于此关键字的值,则对象实例对“maxProperties”有效。
minProperties
此关键字的值必须是非负整数。
如果对象实例的属性数大于或等于此关键字的值,则该实例对“minProperties”有效。
省略此关键字的行为与值0相同。
required
该关键字的值必须是一个数组。这个数组的元素,如果有的话,必须是字符串,并且必须是唯一的
如果数组中的每个项都是实例中属性的名称,则对象实例对此关键字有效。
省略此关键字与空数组具有相同的行为。
properties
“properties”的值必须是一个对象。该对象的每个值必须是有效的JSON格式。
此关键字确定子实例如何验证对象,而不直接验证直接实例本身。
如果每一个出现在实例中的名称,同时也作为一个名称包含在该关键字的值中,那么这个名称的子实例,成功被相应的schema验证,则验证为有效。
省略此关键字与空对象具有相同的行为。
patternProperties
“patternProperties”的值必须是一个对象。根据ECMA 262正则表达式方言,该对象的每个属性名称应该是有效的正则表达式。该对象的每个属性值必须是有效的JSON格式。
此关键字确定子实例如何验证对象,而不直接验证直接实例本身。针对此关键字验证原始实例类型总是成功的。
如果对于与此关键字的值中显示为属性名称的任何正则表达式匹配的每个实例名称,验证成功,则该名称的子实例将成功验证与匹配正则表达式对应的每个模式。
省略此关键字与空对象具有相同的行为。
additionalProperties
“additionalProperties”的值必须是有效的JSON模式。
此关键字确定子实例如何验证对象,而不直接验证直接实例本身。
使用“additionalProperties”进行验证仅适用于与“properties”中的任何名称都不匹配的实例名称的子值,并且不匹配“patternProperties”中的任何正则表达式。
对于所有此类属性,如果子实例针对“additionalProperties”架构进行验证,则验证成功。
省略此关键字与空架构具有相同的行为。
dependencies
此关键字指定在实例是对象且包含特定属性时计算的规则。
该关键字的值必须是一个对象。每个属性指定一个依赖项。每个依赖项值必须是一个数组或一个有效的JSON Schema。
如果依赖项值是子模式,并且依赖项键是实例中的属性,则整个实例必须针对依赖项值进行验证。
如果依赖项值是一个数组,那么数组中的每个元素(如果有的话)必须是一个字符串,并且必须是唯一的。如果依赖关键字是实例中的属性,则依赖关系值中的每个项必须是实例中存在的属性。
省略此关键字与空对象具有相同的行为。
propertyNames
“propertyNames”的值必须是有效的JSON格式。
如果实例是对象,则此关键字将验证实例中的每个属性名称是否针对提供的schema进行验证。请注意,schema正在测试的属性名称将始终为字符串。
省略此关键字与空架构具有相同的行为。
3.2.6 使用条件应用于子模式的关键字
这些关键字一起工作以基于另一个子模式的结果实现子模式的条件应用。
if
此关键字的值必须是有效的JSON格式。
此关键字的子模式的验证结果对整体验证结果没有直接影响。相反,它控制了哪个“then”或“else”关键字被判断。
成功验证此关键字的子模式的实例必须对“then”关键字的子模式值(如果存在)有效。
无法针对此关键字的子模式进行验证的实例也必须对“else”关键字的子模式值(如果存在)有效。
then
此关键字的值必须是有效的JSON格式。
当“if”存在且实例成功验证其子模式时,如果实例也成功验证此关键字的子模式,则valiation将成功对该关键字进行验证。
当“if”不存在时,或者实例无法针对其子模式进行验证时,此关键字无效。
else
此关键字的值必须是有效的JSON格式。
当“if”存在且实例无法针对其子模式进行验证时,如果实例成功验证此关键字的子模式,则valiation将成功对该关键字进行验证。
当“if”不存在时,或者实例成功验证其子模式时,此关键字无效。
3.2.7 使用布尔逻辑应用子模式的关键字
allOf
该关键字的值必须是非空数组。数组的每个项必须是有效的JSON模式。
如果实例针对此关键字的值定义的所有模式成功验证,则实例将针对此关键字成功验证。
anyOf
该关键字的值必须是非空数组。数组的每个项必须是有效的JSON模式。
如果实例针对此关键字的值定义的至少一个模式成功验证,则实例将针对此关键字成功验证。
oneOf
该关键字的值必须是非空数组。数组的每个项必须是有效的JSON模式。
如果实例针对此关键字的值定义的一个模式成功验证,则实例将针对此关键字成功验证。
not
此关键字的值必须是有效的JSON模式。
如果实例无法针对此关键字定义的模式成功验证,则该实例对此关键字有效。
3.3 使用"format"格式进行语义验证
3.3.1 前言
仅结构验证可能不足以验证实例是否满足应用程序的所有要求。
“format”关键字被定义为允许由权威资源准确描述的固定值子集的可互操作语义验证。
此关键字的值称为格式属性。它必须是一个字符串。格式属性通常只能验证给定的一组实例类型。如果要验证的实例的类型不在此集合中,则此格式属性和实例的验证应该成功。
3.3.2 定义的格式
- 日期和时间
- 电子邮件地址
- 主机名
- IP地址
- 资源标识符
- URI模版
- json指针
- 正则表达式
3.4 字符串编码 非json数据
3.4.1 前言
本节中定义的属性表示实例包含以JSON字符串编码的非JSON数据。它们描述了内容的类型及其编码方式。
这些属性提供了将JSON数据解释为丰富的多媒体文档所需的其他信息。
contentEncoding
如果实例值是字符串,则此属性定义字符串应该被解释为二进制数据,并使用此属性命名的编码进行解码。
该属性的值必须是一个字符串。
如果描述的实例不是字符串,则应该忽略此属性的值。
contentMediaType
此属性的值必须是媒体类型
该属性的值必须是一个字符串。
如果描述的实例不是字符串,则应该忽略此属性的值。
如果“contentEncoding”属性不存在,但实例值是一个字符串,那么该属性的值应该指定一个文本文档类型,字符集应该是JSON字符串值被解码到的字符集(对于其中默认为Unicode)。
例1:
{
"type": "string",
"contentEncoding": "base64",
"contentMediaType": "image/png"
}
此架构描述的实例应为字符串,其值应可解释为base64编码的PNG图像。
例2:
{
"type": "string",
"contentMediaType": "text/html"
}
此架构描述的实例应该是包含HTML的字符串,使用JSON字符串被解码为的任何字符集(默认为Unicode)。
3.5 用definitions重用schema
“definitions”
关键字为模式作者提供了标准化的位置,以便将可重用的JSON模式内联到更通用的模式中。关键字不会直接影响验证结果。
该关键字的值必须是一个对象。该对象的每个成员值必须是有效的JSON模式。
例如:
{
"type": "array",
"items": { "$ref": "#/definitions/positiveInteger" },
"definitions": {
"positiveInteger": {
"type": "integer",
"exclusiveMinimum": 0
}
}
}
这里是描述正整数数组的schema,其中正整数约束是“definitions”中的子schema:
3.6 schema注释
title
description
这两个关键字的值必须是一个字符串。
default
此关键字的值没有任何限制。当此关键字的多次出现适用于单个子实例时,实现应该删除重复项。
此关键字可用于提供与特定架构关联的默认JSON值。建议默认值对关联的模式有效。
readOnly
writeOnly
这些关键字的值必须是布尔值。当这些关键字的多次出现适用于单个子实例时,如果任何出现指定了一个真值,则结果值必须为true,否则必须为false。
examples
该关键字的值必须是一个数组。对数组中的值没有任何限制。当此关键字的多次出现适用于单个子实例时,实现必须提供所有值的平面数组,而不是数组数组。
网友评论