JSON Schema详解

2,386 阅读10分钟

「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战」。

1 什么是JSON?

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它基于JavaScript的一个子集,易于人的编写和阅读,也易于机器解析。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java,Go、JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语言。JSON官网

2 JSON数据结构说明

JSON的核心是建立在以下数据结构之上的,JSON由两种结构组成:

  • 键值对的无序集合——对象(或者叫记录、结构、字典、哈希表、有键列表或关联数组等)
  • 值的有序列表——数组

2.1 object

{ "key1": "value1", "key2": "value2" }

2.2 array

[ "first", "second", "third" ]

2.3 number

42
3.1415926

2.4 string

"This is a string"

2.5 boolean

true
false

2.6 null

null

2.7 JSON示例

使用这些简单的数据类型,可以表示各种结构化数据。JSON的灵活性使得同一概念可以用无数种方式来表示。例如,可以用JSON以不同的方式表示一个人的信息:

{
  "name": "zhangsan",
  "mobile": "13688089999",
  "hobby":[ "Sing", "Travel", "Football" ],
  "age": 30,
  "birthday": "February 22, 1990",
  "address": "China, chengdu, Chunxi Road"
}

{
  "name": "zhangsan",
  "mobile": "13688089999",
  "hobby":[ "Sing", "Travel", "Football" ],
  "age":30,
  "birthday": "1990-02-22",
  "address": {
    "street_address": "Chunxi Road",
    "city": "chengdu",
    "country": "China"
  }
}

2.8 JSON Schema示例优化

尽管上面其中一种表述明显比另一种更正式,但是这两种表述都同样有效。然而,当应用程序说 “给我一个JSON记录”时,准确地知道该记录应该如何组织是很重要的。例如,我们需要知道需要哪些字段,以及值是如何表示的。这就是 JSON Schema 的用武之地。下面的 JSON Schema 片段描述了上面第二个示例的结构。现在不要太担心细节问题。它们将在后面的章节中进行解释。

{
    "$schema":"http://json-schema.org/draft-07/schema",
    "$id":"http://example.com/example.json",
    "type":"object",
    "title":"The Root Schema",
    "description":"The root schema comprises the entire JSON document.",
    "required":[
        "name",
        "mobile",
        "hobby",
        "age",
        "birthday",
        "address"
    ],
    "properties":{
        "name":{
            "$id":"#/properties/name",
            "type":"string",
            "title":"The Name Schema",
            "description":"An explanation about the purpose of this instance.",
            "default":"",
            "examples":[
                "zhangsan"
            ]
        },
        "mobile":{
            "$id":"#/properties/mobile",
            "type":"string",
            "title":"The Mobile Schema",
            "description":"An explanation about the purpose of this instance.",
            "default":"",
            "examples":[
                "13688089999"
            ]
        },
        "hobby":{
            "$id":"#/properties/hobby",
            "type":"array",
            "title":"The Hobby Schema",
            "description":"An explanation about the purpose of this instance.",
            "default":[

            ],
            "items":{
                "$id":"#/properties/hobby/items",
                "type":"string",
                "title":"The Items Schema",
                "description":"An explanation about the purpose of this instance.",
                "default":"",
                "examples":[
                    "Sing",
                    "Travel",
                    "Football"
                ]
            }
        },
        "age":{
            "$id":"#/properties/age",
            "type":"integer",
            "title":"The Age Schema",
            "description":"An explanation about the purpose of this instance.",
            "default":0,
            "examples":[
                30
            ]
        },
        "birthday":{
            "$id":"#/properties/birthday",
            "type":"string",
            "title":"The Birthday Schema",
            "description":"An explanation about the purpose of this instance.",
            "default":"",
            "examples":[
                "1990-02-22"
            ]
        },
        "address":{
            "$id":"#/properties/address",
            "type":"object",
            "title":"The Address Schema",
            "description":"An explanation about the purpose of this instance.",
            "default":{

            },
            "examples":[
                {
                    "street_address":"chun xi lu",
                    "city":"chengdu",
                    "country":"china"
                }
            ],
            "required":[
                "street_address",
                "city",
                "country"
            ],
            "properties":{
                "street_address":{
                    "$id":"#/properties/address/properties/street_address",
                    "type":"string",
                    "title":"The Street_address Schema",
                    "description":"An explanation about the purpose of this instance.",
                    "default":"",
                    "examples":[
                        "chun xi lu"
                    ]
                },
                "city":{
                    "$id":"#/properties/address/properties/city",
                    "type":"string",
                    "title":"The City Schema",
                    "description":"An explanation about the purpose of this instance.",
                    "default":"",
                    "examples":[
                        "chengdu"
                    ]
                },
                "country":{
                    "$id":"#/properties/address/properties/country",
                    "type":"string",
                    "title":"The Country Schema",
                    "description":"An explanation about the purpose of this instance.",
                    "default":"",
                    "examples":[
                        "china"
                    ]
                }
            }
        }
    }
}

3 什么是JSON Schema?

::: tip 定义

4 JSON Schema关键字汇总

Json Schema定义了一系列关键字,元数据通过这些关键字来描述Json数据的规范。其中有些关键字是通用的;有些关键字是针对特定类型的;还有些关键字是描述型的,不影响合法性校验。

关键字描述
$schema表示该JSON Schema文件遵循的规范,当前使用的schema版本
$id为JSON模式声明一个唯一标识符,声明了一个解析*$ref* 的URI时的基础URI。
title为该JSON Schema文件提供一个标题
description关于该JSON Schema文件的描述信息
format仅进行结构验证可能不足以验证实例是否满足应用程序的所有需求。
default指定项的默认值。尽管许多JSON模式验证器会忽略这个关键字,但是在可能的情况下,JSON处理器可以使用此关键字的值为丢失的键值对提供默认值。
examples这个关键字的值必须是一个数组,提供一组满足JSON模式的实例,用于向读者解释JSON模式的作用和效果。
$comment这个关键字完全是为了用于向JSON模式源添加注释。此关键字的值必须是字符串。
$ref用来引用同一个JSON模式文件或其他JSON模式文件中的JSON模式片段,这个属性的值通常是一个相对或者绝对URI。
definitions可以在JSON模式中定义一个可以在这个JSON模式中被引用的JSON子模式
type表示待校验元素的类型(例如,最外层的type表示待校验的是一个JSON对象,内层type分别表示待校验的元素类型为,整数,字符串,数字)
enum值必须是一个数组。这个数组应该至少有一个元素。数组中的元素应该是惟一的。
multipleOf用于约束取值,值必须是一个严格大于0的数字。只有当数值实例除以这个关键字的值等于一个整数时才能验证通过。
maximum用于约束取值范围,表示取值范围应该小于或等于maximum,只有当实例小于等于这个关键字的值时才能验证通过。
minimum用于约束取值范围,表示取值范围应该大于或等于minimum
exclusiveMinimum如果minimum和exclusiveMinimum同时存在,且exclusiveMinimum的值为true,则表示取值范围只能大于minimum
exclusiveMaximum如果maximum和exclusiveMaximum同时存在,且exclusiveMaximum的值为true,则表示取值范围只能小于maximum
maxLength字符串类型数据的最大长度
minLength字符串类型数据的最小长度
pattern使用正则表达式约束字符串类型数据
items该关键字的值必须是一个有效的JSON模式或一个有效的JSON模式数组。此关键字用来验证数组实例中的每个值,而不是直接验证实例本身。
additionalItems此关键字的值必须是一个有效的JSON模式或者一个布尔值。此关键字用来验证数组中的元素,而不是直接验证直接实例本身。
maxItems此关键字的值必须是一个非负整数。如果一个数组实例的大小小于等于此关键字的值,则验证通过。
minItems此关键字的值必须是一个非负整数。如果一个数组实例的大小大于等于此关键字的值,则验证通过
uniqueItems此关键字的值必须是一个布尔值。如果此关键字的值为布尔值 false,则数组实例验证通过
contains此关键字的值必须是一个有效的JSON模式。如果一个数组实例中至少有一个元素能通过此关键字指定的JSON模式的验证,则验证通过。
maxProperties此关键字的值必须是一个非负整数,如果一个对象的属性个数小于等于此关键字的值,则验证通过。
minProperties此关键字的值必须是一个非负整数,如果一个对象的属性个数大于等于此关键字的值,则验证通过。
required此关键字的值必须是一个数组。数组中的每一个元素(如果有的话)必须是一个字符串,并且必须是唯一的。如果此关键字的值中的每一个元素都是对象实例中某个属性的名称,则验证通过。
properties定义待校验的JSON对象中,各个key-value对中value的限制条件.这个对象中的每一个值都必须是一个有效的JSON模式。

5 Json Schema 类型

5.1 Object

object类型有三个关键字:type,properties,required,如下:

关键字描述
type类型
properties定义属性
required必需属性
maxProperties最大属性个数
minProperties最小属性个数
additionalPropertiestrue or false or object
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product",
    "description": "A product from Acme's catalog",
    "type": "object",
    "properties": {
        "id": {
            "description": "The unique identifier for a product",
            "type": "integer"
        },
        "name": {
            "description": "Name of the product",
            "type": "string"
        },
        "price": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true
        }
    },
    "required": ["id", "name", "price"]
}

5.2 array

array有三个单独的属性:items,minItems,uniqueItems:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product",
    "description": "A product from Acme's catalog",
    "type": "array",
    "items": {
        "type": "string"
     },
     "minItems": 1,
     "uniqueItems": true
    }
关键字描述示例
itemsarray 每个元素的类型.
minItems约束属性,数组最小的元素个数
maxItems约束属性,数组最大的元素个数
uniqueItems约束属性,每个元素都不相同
additionalProperties约束items的类型,不建议使用示例
Dependencies属性依赖用法
patternProperties用法

5.3 string

关键字描述
maxLength定义字符串的最大长度,>=0
minLength定义字符串的最小长度,>=0
pattern用正则表达式约束字符串
{
   "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product",
    "description": "A product from Acme's catalog",
    "type": "object",
    "properties": {
        "ip": {
            "mail": "string",
            "pattern":"w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*"
        },
        "host": {
            "type": "phoneNumber",
            "pattern":"((d{3,4})|d{3,4}-)?d{7,8}(-d{3})*"
        },
    },
      "required": ["ip", "host"]
  }

5.4 integer

关键字描述
minimum最小值
exclusiveMinimum如果存在 "exclusiveMinimum" 并且具有布尔值 true,如果它严格意义上大于 "minimum" 的值则实例有效。
maximum约束属性,最大值
exclusiveMaximum如果存在 "exclusiveMinimum" 并且具有布尔值 true,如果它严格意义上小于 "maximum" 的值则实例有效。
multipleOf是某数的倍数,必须大于0的整数
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product",
    "description": "A product from Acme's catalog",
    "type": "object",
    "properties": {
        "name": {
            "description": "Name of the product",
            "type": "string"
        },
        "price": {
            "type": "integer",
            "minimum": 0,
            "exclusiveMinimum": true
        }
    },
    "required": ["id", "name", "price"]
}

5.5 number


{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product",
    "description": "A product from Acme's catalog",
    "type": "object",
    "properties": {
        "name": {
            "description": "Name of the product",
            "type": "string"
        },
        "price": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true
        }
    },
    "required": ["id", "name", "price"]
}

5.6 boolean


{
  "type": "object",
  "properties": {
    "number":      { "type": "boolean" },
    "street_name": { "type": "string" },
    "street_type": { "type": "string",
                     "enum": ["Street", "Avenue", "Boulevard"]
                   }
  }
}    

5.7 enum


{
  "type": "object",
  "properties": {
    "number":      { "type": "number" },
    "street_name": { "type": "string" },
    "street_type": ["Street", "Avenue", "Boulevard"]                   
  }
}
{
  "type": "object",
  "properties": {
    "number":      { "type": "number" },
    "street_name": { "type": "string" },
    "street_type": { "type": "string",
                     "enum": ["Street", "Avenue", "Boulevard"]
                   }
  }
}

6 子模式应用关键字

6.1 子模式的条件应用关键字

这些关键字协同工作,根据另一个子模式的结果实现子模式的条件应用。 这些关键字不能跨子模式边界相互交互。换句话说,allOf 中的一个分支中的 if 不能对另一个分支中的 then 或 else 产生影响。 当这些关键字不存在时,它们都没有默认行为。特别是,不能将它们视为带有空模式,当 if 不存在时,必须完全忽略 then 和 else。

关键字描述
if这个关键字指定的JSON模式的的验证结果对整个验证结果没有直接影响,而是用来控制 then 或 else 中的哪个关键字中的JSON模式被用来进行判断。
then如果存在 if 关键字,并且实例成功通过了 if 关键字指定的JSON模式的验证,那么如果实例也成功通过了这个关键字指定的JSON模式的验证,那么则该关键字验证通过。
else如果存在 if 关键字,而实例未能对其指定的JSON模式进行验证,那么如果实例成功通过了该关键字指定的JSON模式的验证,那么则该关键字验证通过

6.1.1 条件子模式举例说明

如果我们用如下的JSON模式来处理美国和加拿大的地址。这些国家的邮政编码的格式不一样,我们想要根据地址所处的国家来验证邮政编码的格式。如果是美国的地址,则邮政编码字段由5位数字和可选的4位数字后缀组成,如果是加拿大的地址,则邮政编码是固定的6位长度的数字和大写字母组合。

{
  "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-Z0-9]{6}" } }
  }
}

上面的例子只能处理两个国家的地址,如果要处理多个国家的地址,可以使用 allOf 关键字将 if-then 关键字组合起来使用,如下所示:

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

6.2 使用布尔逻辑子模式的关键字

这些关键字的值必须是一个非空数组,并且数组中的每一个元素必须是一个有效的JSON模式。

关键字描述
allOf如果一个实例成功通过这个关键字指定的所有JSON模式,则验证通过
anyOf如果一个实例成功通过了这个关键字指定的至少一个JSON模式的验证,则验证通过。
oneOf如果一个实例成功通过了这个关键字指定的其中一个JSON模式的验证,则验证通过。
not如果一个实例对于这个关键字指定的JSON模式验证失败,则验证通过。

6.2.1 布尔逻辑子模式示例

allOf

意思是展示全部属性,建议用requires替代, 不建议使用,示例如下

{
  "definitions": {
    "address": {
      "type": "object",
      "properties": {
        "street_address": { "type": "string" },
        "city":           { "type": "string" },
        "state":          { "type": "string" }
      },
      "required": ["street_address", "city", "state"]
    }
  },
 
  "allOf": [
    { "$ref": "#/definitions/address" },
    { "properties": {
        "type": { "enum": [ "residential", "business" ] }
      }
    }
  ]
}

anyOf

意思是展示任意属性,建议用requires替代和minProperties替代。 我们用如下一个JSON模式验证一个实例是否能满足是字符串,值在"Ruby"、"Java"、"Swift" 之中,值等于"Python"这三个条件中至少一个条件:

{
  "anyOf": [
    {"type": "string"},
    {"enum": ["Ruby", "Java", "Swift"]},
    {"const": "Python"},
    {"type": "number" }
  ]
}

oneOf

我们用如下一个JSON模式验证一个实例是否是字符串、对象或者数组之一:

{
  "oneOf": [
    {"type": "string"},
    {"type": "object"},
    {"type": "array"},
    { "type": "number", "multipleOf": 5 },
    { "type": "number", "multipleOf": 3 }
  ]
}

not

非 * 类型,我们用如下的JSON模式表示不允许字符串实例:

{
  "not": {"type": "string"}
}

7 验证语义的关键字 format

仅进行结构验证可能不足以验证实例是否满足应用程序的所有需求。定义format关键字是为了允许对权威资源(无论是rfc还是其他外部规范)精确描述的固定值子集进行互操作语义验证。 这个关键字的值称为格式属性,必须是string类型。format属性通常只能验证给定的一组实例类型。如果要验证的实例类型不在此集合中,则此格式属性和实例的验证应该成功。 已定义的格式有如下几种,并且这些属性只应用于字符串类型的实例:

7.1 日期和时间

  • date
  • time
  • datetime

7.2 电子邮件地址

  • email
  • idn-email

7.3 主机名

  • hostname
  • idn-hostname

7.4 IP地址

  • ipv4
  • ipv6

7.5 资源标识符

  • uri
  • uri-reference
  • iri
  • iri-reference

7.6 URI模版

  • uri-template

7.7 JSON指针

  • json-pointer
  • relative-json-pointer

7.8 正则表达式

  • regex

7.9 验证format示例

{
  "$id": "https://www.lsdcloud.com/identity.schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Person",
  "type": "object",
  "properties": {
    "email": {
      "type": "string",
      "format": "email",
      "title": "E-Mail",
      "minLength": 3
         }
  },
  "required": [
    "email"
  ],
  "additionalProperties": false
}

8 JSON Schema进阶

了解了上面的各个类型的定义及约定条件,就可以满足大部分情况了。但为了写出更好的json schema,我们再学习几个关键字

8.1 $ref

$ref 用来引用其它schema,

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product set",
    "type": "array",
    "items": {
        "title": "Product",
        "type": "object",
        "properties": {
            "id": {
                "description": "The unique identifier for a product",
                "type": "number"
            },
            "name": {
                "type": "string"
            },
            "price": {
                "type": "number",
                "minimum": 0,
                "exclusiveMinimum": true
            },
            "tags": {
                "type": "array",
                "items": {
                    "type": "string"
                },
                "minItems": 1,
                "uniqueItems": true
            },
            "dimensions": {
                "type": "object",
                "properties": {
                    "length": {"type": "number"},
                    "width": {"type": "number"},
                    "height": {"type": "number"}
                },
                "required": ["length", "width", "height"]
            },
            "warehouseLocation": {
                "description": "Coordinates of the warehouse with the product",
                "$ref": "http://json-schema.org/geo"
            }
        },
        "required": ["id", "name", "price"]
    }
}

8.2 definitions

当一个schema写的很大的时候,可能需要创建内部结构体,再使用$ref进行引用,示列如下:

{
  "$schema": "http://json-schema.org/draft-07/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" }
  }
}

9 整体示例说明

{
    # 该关键字用于指定JSON Schema版本: draft-07
    "$schema": "http://json-schema.org/draft-07/schema#",
    # 描述对应的JSON元素,title相对来说,更加简洁
    "title": "book info",
    # 描述对应的JSON元素,description更加倾向于详细描述相关信息
    "description": "some information about book",
    # 该关键字用于限定待校验JSON元素所属的数据类型,取值可为:object,array,integer,number,string,boolean,null
    "type": "object",
    # 用于指定JSON对象中的各种不同key应该满足的校验逻辑,
    # 如果待校验JSON对象中所有值都能够通过该关键字值中定义的对应key的校验逻辑,每个key对应的值,都是一个JSON Schema,则待校验JSON对象通过校验。
    "properties": {
        "id": {
            "description": "The unique identifier for a book",
            "type": "integer",
            "minimum": 1
        },
        "name": {
            "description": "book name",
            "type": "string",
            "minLength": 3,
            "maxLength": 30
        },
        "info": {
            "description": "simple information about book",
            "type": "string",
            "minLength": 10,
            "maxLength": 60
        },
        "tips": {
            "anyOf": [  # 满足其中一个类型 就行
                {"type": "string", "minLength": 10, "maxLength": 60}, 
                {"type": "number", "minimum": 5.0}
            ]
        },
        "price": {
            "description": "book price",
            "type": "number",
            # 能被0.5整除
            "multipleOf": 0.5,
            # 这里取等,5.0=<price<=99999.0
            "minimum": 5.0,
            "maximum": 99999.0,
            # 若使用下面这两个关键字则 5.0<price<99999.0
            # "exclusiveMinimum": 5.0,
            # "exclusiveMaximum": 99999.0
        },
        "tags": {
            "type": "array",
            "items": [
                {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 8
                },
                {
                    "type": "number",
                    "minimum": 1.0
                }
            ],
            # 待校验JSON数组第一个元素是string类型,且可接受的最短长度为5个字符,第二个元素是number类型,且可接受的最小值为10
            # 剩余的其他元素是string类型,且可接受的最短长度为2"additonalItems": {
                "type": "string",
                "miniLength": 2
            },
            # 至少一个
            "miniItems": 1,
            # 最多5"maxItems": 5,
            # 值为true时,所有元素都具有唯一性时,才能通过校验。
            "uniqueItems": True
        },
        "date": {
            "description": "书籍出版日期",
            "type": "string",
            # 可以是以下取值:date、date-time(时间格式)、email(邮件格式)、hostname(网站地址格式)、ipv4、ipv6、uri等。
            # 使用format关键字时,在实例化validator时必须给它传format_checker参数,值如:draft7_format_checker, 网址:
            # https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.Draft7Validator
            "format": "date",
        },
        "bookcoding": {
            "description": "书籍编码",
            "type": "string",
            # 符合该关键字指定的正则表达式,才算通过校验。
            "pattern": "^[A-Z]+[a-zA-Z0-9]{12}$"
        },
        "other": {
            "description": "其他信息",
            "type": "object",
            "properties": {
                "info1": {
                    "type": "string"
                },
                "info2": {
                    "type": "string"
                }
            }
        }
    },
    # 指定了待校验JSON对象可以接受的最少 一级key 的个数
    "minProperties": 3,
    # 指定了待校验JSON对象可以接受的最多 一级key 的个数。
    "maxProperties": 7,
    # patternProperties对象的每一个一级key都是一个正则表达式,value都是一个JSON Schema。
    # 只有待校验JSON对象中的一级key,通过与之匹配的patternProperties中的一级正则表达式,对应的JSON Schema的校验,才算通过校验。
    # 下面的JSON Schema表示, 所有以a开头的一级key的value都必须是number,
    "patternProperties": {
        "^a": {
            "type": "number"
        },
    },
    # 如果待校验JSON对象中存在,既没有在properties中被定义,又没有在patternProperties中被定义,那么这些一级key必须通过additionalProperties的校验。
    "additionalProperties": {
        "desc": {
            "type": "string",
            "minLength": 1
        },
    },
    # 该关键字限制了JSON对象中必须包含哪些一级key。
    # 如果一个JSON对象中含有required关键字所指定的所有一级key,则该JSON对象能够通过校验。
    "required": ["id", "name", "info", "price"]
}

10 更多参考资料