admin 管理员组

文章数量: 887021

Json

Json-schema

前端与服务器端的交互过程,大部分时候是使用的json格式

对于json还是比较了解,可是json-schema是什么?

json–JavaScript Object Notation JavaScript对象表示法

json-schema是一个用于验证json数据格式的工具,它本身也是使用json语言编写的

Json Schema定义了一套词汇和规则,这套词汇和规则用来定义Json元数据,且元数据也是通过Json数据形式表达的。Json元数据定义了Json数据需要满足的规范,规范包括成员、结构、类型、约束等

Json-schema示例

json-schema举例:

{"$schema": "","$id": "","$vocabulary": {"": true,"": true,"": true,"": true,"": false,"": true},"$recursiveAnchor": true,"title": "Core and Validation specifications meta-schema","allOf": [{"$ref": "meta/core"},{"$ref": "meta/applicator"},{"$ref": "meta/validation"},{"$ref": "meta/meta-data"},{"$ref": "meta/format"},{"$ref": "meta/content"}],"type": ["object", "boolean"],"properties": {"definitions": {"$comment": "While no longer an official keyword as it is replaced by $defs, this keyword is retained in the meta-schema to prevent incompatible extensions as it remains in common use.","type": "object","additionalProperties": { "$recursiveRef": "#" },"default": {}},"dependencies": {"$comment": "\"dependencies\" is no longer a keyword, but schema authors should avoid redefining it to facilitate a smooth transition to \"dependentSchemas\" and \"dependentRequired\"","type": "object","additionalProperties": {"anyOf": [{ "$recursiveRef": "#" },{ "$ref": "meta/validation#/$defs/stringArray" }]}}}
}

在上述文件中,有些是json-schema规定的特殊字符,也即具有特殊涵义的字符,我们称之为关键字或保留字,有些是根据我们的需要随便编写的相关内容,

关键字说明

关键字描述示例
$schema主要用于声明当前文件使用的json模式,遵守的是那个版本json模式的规范上述示例是遵守2019-09发布的那个版本
$id用于作为模式的唯一标识符,一般指向一个自主域名。方便后续引用
$ref引用一个定义的模式
$vocabulary
$recursiveAnchor
$recursiveRef
$comment仅仅是为模式添加注释用(New in draft 7)
type类型:string\number\boolean\array\object\null
properties属性,用于定义对象中的属性
required用于定义对象中必须含有的属性
enum表示json数据的取值只能是list中的某个数组
title标题,用它给我们的模式提供了标题
description关于模式的描述。
default默认值
example一个符合约束条件的模式示例

title,description,default,example只作为描述作用,不影响对数据的校验。

对复杂结构的支持包括定义和引用。当多个元素使用相同的校验模式时,可以将相同的结构校验定义成一个“类型”,需要使用该“类型”时,可以通过其路径或id来引用

definations-用于定义通用类型模式

定义一个类型,并不需要特殊的关键字。通常的习惯是在root节点的 definations 下面,定义需要多次引用的schema。definations是一个json对象,key是想要定义的“类型”的名称,value是一个json schema

{"definitions": {"address": {//定义的一个通用的模式"type": "object","properties": {"street_address": { "type": "string" },"city":           { "type": "string" },"state":          { "type": "string" }},"required": ["street_address", "city", "state"]}},"type": "object","properties": {"billing_address": { "$ref": "#/definitions/address" },"shipping_address": { "$ref": "#/definitions/address" }}
}

$ref

上例中定义了一个address的schema,并且在两个地方通过路径的方式引用了它,#/definitions/address表示从根节点开始的路径

$id

{"definitions": {"address": {//定义的一个通用的模式"type": "object","$id" : "address","properties": {"street_address": { "type": "string" },"city":           { "type": "string" },"state":          { "type": "string" }},"required": ["street_address", "city", "state"]}},"type": "object","properties": {"billing_address": { "$ref": "#address"},"shipping_address": { "$ref":"#address"}}
}

可以在上面的定义中加入id属性,这样可以通过id属性的值对该schema进行引用,而不需要完整的路径。

type

定义模式属性的类型,可以是单选也可以提供多个类型:

type的可选值包括:string\number\boolean\array\object\null

仅有一个类型可选:{ "type": "string" }

可以有多个类型可选:{ "type": ["number", "string"] }

当type与enum发生冲突的时候,以type约束为先:

{"type": "string","enum": ["red", "amber", "green", null]
}

null值与"type": "string"冲突,此时若选值null则检测不通过

约束条件

string 类型的约束条件

关键字描述取值类型
maxLength字符串实例字符的最大长度(非负)≥0
minLength字符串实例字符的最小长度(非负)≥0
pattern限定字符串应符合的表达式条件,符合则有效表达式
formatJson Schema内建的一些规则,对字符串的格式做约束,例如电子邮件、日期、域名等

format包括"date", “time”, “date-time”, “email”, “hostname”,“ipv4”,"uri"等
“json-pointer”,“regex”

number类型的约束条件

number:数字类型
integer:必须是整数

关键字描述取值类型
minimum表示可以接受的最小值。 x ≥ minimum数值型
maximum表示可以接受的最大值。 x ≤ maximum数值型
exclusiveMinimum开区间最小值,排除等于的情况。x > exclusiveMinimum数值型
exclusiveMaximum开区间最大值,排除等于的情况。x < exclusiveMaximum数值型
multipleOf要求数值必须是该指定值的整数倍数值型

array类型的约束条件

关键字描述取值类型
minItems表示数组内最少元素个数数值型
maxItems表示数组内最多元素个数数值型
items要求数组内每个成员都是某种类型{“type”: “number”}或者[{“type”: “number”},{“type”: “string”}]
additionalItems数组是否允许额外成员,配合items使用booloan,或限制条件
uniqueItems约束数组中每项不得重复booloan
contains最少有一个符合条件

示例:

  "type": "array","items": [{//0"type": "number"},{//1"type": "string"},{//2"type": "string","enum": ["Street", "Avenue", "Boulevard"]},{//4"type": "string","enum": ["NW", "NE", "SW", "SE"]}],"minItems": 1,"maxItems": 5,"additionalItems": {"type": "string","minLength": 2},"uniqueItems": true
}

items & additionalItems

items列出了多个约束条件时,对应索引的项如果存在必须符合约束条件

  • additionalItems属性不存在

    • 数组长度小于items,只要存在的项符合约束条件即可,也即数组长度可以小于items
    • 数组长度大于items且额外元素没有约束条件
  • 存在additionalItems属性,数组的长度受限于 additionalItems:

    • 数组长度若小于items,只要存在的项符合约束条件即可,不受 additionalItems影响
    • 如果additionalItems为true,没有额外约束,数组长度可以大于items,因为后面的元素没有对应索引的items约束条件因此无约束

示例:

{"type": "array","items": [{"type": "number"},{"type": "string"},{"type": "string","enum": ["Street", "Avenue", "Boulevard"]},{"type": "string","enum": ["NW", "NE", "SW", "SE"]}],"additionalItems": true
}
  • 如果additionalItems 有额外的约束,额外的元素必须符合additionalItems 的约束条件
  "type": "array","items": [{//0"type": "number"},{//1"type": "string"}],"minItems": 1,"maxItems": 5,"additionalItems": {"type": "string","minLength": 2},"uniqueItems": true
}
  • 如果additionalItems为 false,数组长度只能<=items的长度
{"type": "array","items": [{"type": "number"},{"type": "string"},{"type": "string","enum": ["Street", "Avenue", "Boulevard"]},{"type": "string","enum": ["NW", "NE", "SW", "SE"]}],"additionalItems": false
}

contains(New in draft 6)

示例:

{"type": "array","contains": {"type": "number"}
}
e.g :["life", "universe", "everything", 42]//最少有一个符合条件

object类型的约束条件

关键字描述取值类型
required约束对象必须具有的属性字段数组
properties用于定义对象属性和对应值的类型,以及用于 JSON 文件中的最小值和最大值。
propertyNames用于定义对象properties中的属性名称需要满足的约束
patternProperties批量定义对象Schema
dependencies规定某些属性之间的依赖,不能在依赖属性缺席的情况下单独出现,属于数据完整性方面的约束。
additionalProperties规定object类型是否允许出现不在properties中规定的属性可以取true/false,或者直接设置约束规则
minProperties规定最少有几个属性成员
maxProperties规定最多有几个属性成员
const用于设定属性的值

propertyNames(New in draft 6)

示例:

{"type": "object","propertyNames": {"pattern": "^[A-Za-z_][A-Za-z0-9_]*$"}
}

const(New in draft 6)

设定值后不允许属性设置为其他值

{ “const”: “United States of America” }
等价于
{ “enum”: [ “United States of America” ] }

dependencies

属性间的依赖

{"type": "object","properties": {"name": { "type": "string" },"credit_card": { "type": "number" },"billing_address": { "type": "string" }},"required": ["name"],"dependencies": {"credit_card": ["billing_address"],"billing_address": ["credit_card"]}
}

单独定义依赖的属性模式

{"type": "object","properties": {"name": { "type": "string" },"credit_card": { "type": "number" }},"required": ["name"],"dependencies": {//credit_card依赖的属性"credit_card": {"properties": {"billing_address": { "type": "string" }},"required": ["billing_address"]}}
}

只要credit_card属性存在,billing_address必须存在

additionalProperties

用法类似于additionalItems

additionalProperties不受properties与patternProperties的约束条件限制

{"type": "object","properties": {"builtin": { "type": "number" }},"patternProperties": {"^S_": { "type": "string" },"^I_": { "type": "integer" }},"additionalProperties": { "type": "string" }
}

逻辑组合的约束条件

关键字描述取值类型
allOf满足所有约束条件,"allOf"的内容是一个数组,数组内的成员都是内嵌的Json Schema
anyOf满足anyOf数组中的任意个Schema
oneOf满足且仅满足oneOf数组中的一个Schema
not它告诉Json不能满足not所对应的Schema

需要注意,使用allOf时,Schema不论在内嵌的Schema里还是外部的Schema里,都不应该使"additionalProperties"为false。否则可能会生成任何数据都无法满足的矛盾Schema。

非json格式数据转化(New in draft 7)

{"type": "string","contentEncoding": "base64","contentMediaType": "image/png"
}

if then else

{"type": "object","properties": {"street_address": {"type": "string"},"country": {"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]" } }}
}

以下示例通过 if then实现了 allOf 等同于 oneOf

{"type": "object","properties": {"street_address": {"type": "string"},"country": {"enum": ["United States of America", "Canada", "Netherlands"]}},"allOf": [{"if": {"properties": { "country": { "const": "United States of America" } }},"then": {"properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }}},{"if": {"properties": { "country": { "const": "Canada" } }},"then": {"properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }}},{"if": {"properties": { "country": { "const": "Netherlands" } }},"then": {"properties": { "postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" } }}}]
}

本文标签: Json