Json Schema 快速入门
JSON 模式是一种基于 JSON 格式定义 JSON 数据结构的规范。它被写在 IETF 草案下并于 2011 年到期。JSON 模式:
- 描述现有数据格式。
- 干净的人类和机器可读的文档。
- 完整的结构验证,有利于自动化测试。
- 完整的结构验证,可用于验证客户端提交的数据。
Json schema 格式
Json schema 本身遵循Json规范,本身就是一个Json字符串,先来看一个例子
{
"$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"]
}
我们来看一下json schema 最外层包含以下几个字段
$schema | 描述 | 示例 |
---|---|---|
$schema | $schema 关键字状态,表示这个模式与 v4 规范草案书写一致。 | |
title | 标题,用来描述结构 | |
description | 描述 | |
type | 类型 | . |
properties | 定义属性 | |
required | 必需属性 |
上面只是一个简单的例子,从上面可以看出Json schema 本身是一个JSON字符串,由通过key-value的形式进行标示。
type 和 properties 用来定义json 属性的类型。required 是对Object字段的必段性进行约束。事实上,json Schema定义了json所支持的类型,每种类型都有0-N种约束方式。下一节我们来,细致介绍一下。
Json schema 类型
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"]
}
object类型有三个关键字:type(限定类型),properties(定义object的各个字段),required(限定必需字段),如下:
关键字 | 描述 | 示例 |
---|---|---|
type | 类型 | . |
properties | 定义属性 | |
required | 必需属性 | |
maxProperties | 最大属性个数 | |
minProperties | 最小属性个数 | |
additionalProperties | true or false or object | 参考 |
properties 定义每个属性的名字和类型,方式如上例。
array
{
"$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
}
array有三个单独的属性:items,minItems,uniqueItems:
关键字 | 描述 | 示例 |
---|---|---|
items | array 每个元素的类型 | . |
minItems | 约束属性,数组最小的元素个数 | |
maxItems | 约束属性,数组最大的元素个数 | |
uniqueItems | 约束属性,每个元素都不相同 | |
additionalProperties | 约束items的类型,不建议使用 | 示例 |
Dependencies | 属性依赖 | 用法 |
patternProperties | 用法 |
string
{
"$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"]
}
关键字 | 描述 | 示例 |
---|---|---|
maxLength | 定义字符串的最大长度,>=0 | . |
minLength | 定义字符串的最小长度,>=0 | |
pattern | 用正则表达式约束字符串 |
integer
{
"$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"]
}
关键字 | 描述 | 示例 |
---|---|---|
minimum | 最小值 | . |
exclusiveMinimum | 如果存在 "exclusiveMinimum" 并且具有布尔值 true,如果它严格意义上大于 "minimum" 的值则实例有效。 | |
maximum | 约束属性,最大值 | |
exclusiveMaximum | 如果存在 "exclusiveMinimum" 并且具有布尔值 true,如果它严格意义上小于 "maximum" 的值则实例有效。 | |
multipleOf | 是某数的倍数,必须大于0的整数 |
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"]
}
number 关键字可以描述任意长度,任意小数点的数字。number类型的约束有以下几个:
关键字 | 描述 | 示例 |
---|---|---|
minimum | 最小值 | . |
exclusiveMinimum | 如果存在 "exclusiveMinimum" 并且具有布尔值 true,如果它严格意义上大于 "minimum" 的值则实例有效。 | |
maximum | 约束属性,最大值 | |
exclusiveMaximum | 如果存在 "exclusiveMinimum" 并且具有布尔值 true,如果它严格意义上小于 "maximum" 的值则实例有效。 |
boolean
{
"type": "object",
"properties": {
"number": { "type": "boolean" },
"street_name": { "type": "string" },
"street_type": { "type": "string",
"enum": ["Street", "Avenue", "Boulevard"]
}
}
}
true or false
enum
{
"type": "object",
"properties": {
"number": { "type": "number" },
"street_name": { "type": "string" },
"street_type": { "type": "string",
"enum": ["Street", "Avenue", "Boulevard"]
}
}
}
也可以这么做
{
"type": "object",
"properties": {
"number": { "type": "number" },
"street_name": { "type": "string" },
"street_type": ["Street", "Avenue", "Boulevard"]
}
}
null
进阶
了解了上面的各个类型的定义及约定条件,就可以满足大部分情况了。但为了写出更好的json schema,我们再学习几个关键字
$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"]
}
}
definitions
当一个schema写的很大的时候,可能需要创建内部结构体,再使用$ref进行引用,示列如下:
{
"type": "array",
"items": { "$ref": "#/definitions/positiveInteger" },
"definitions": {
"positiveInteger": {
"type": "integer",
"minimum": 0,
"exclusiveMinimum": true
}
}
}
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替代,示例如下:
{
"anyOf": [
{ "type": "string" },
{ "type": "number" }
]
}
oneOf
其中之一
{
"oneOf": [
{ "type": "number", "multipleOf": 5 },
{ "type": "number", "multipleOf": 3 }
]
}
not
非 * 类型
示例
{ "not": { "type": "string" } }
技术讨论: