以下示例决不包含 JSON Schema 可以提供的所有值。为此,您需要深入了解规范本身——在https://json-schema.org/specification.html了解更多信息。
假设我们正在与基于 JSON 的产品目录进行交互。该目录的产品具有:
productId
productName
price
tags
.例如:
{
"productId": 1,
"productName": "A green door",
"price": 12.50,
"tags": [ "home", "green" ]
}
虽然通常很简单,但该示例留下了一些悬而未决的问题。这里只是其中的几个:
productId
?productName
必需的吗?price
为零(0)吗?tags
字符串值吗?当您谈论数据格式时,您希望获得有关键含义的元数据,包括这些键的有效输入。JSON Schema是一个提议的 IETF 标准,如何回答这些数据问题。
要开始模式定义,让我们从基本的 JSON 模式开始。
我们从四个称为关键字的属性开始,它们表示为JSON键。
是的。该标准使用 JSON 数据文档来描述数据文档,通常也是 JSON 数据文档,但可以是任意数量的其他内容类型,例如
text/xml
.
$schema
关键字表示此模式是根据标准的特定草案编写的,并且出于各种原因使用,主要是版本控制。$id
URI,以及模式中其他 URI 引用所针对的基本 URI。title
和description
注释关键字只是描述性的。它们不会对正在验证的数据添加约束。使用这两个关键字来说明模式的意图。type
第一个约束,在这种情况下它必须是一个 JSON 对象。{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/product.schema.json",
"title": "Product",
"description": "A product in the catalog",
"type": "object"
}
我们在启动模式时引入以下术语:
productId
是唯一标识产品的数值。由于这是产品的规范标识符,因此没有一个产品是没有意义的,因此它是必需的。
在 JSON Schema 术语中,我们更新我们的模式以添加:
properties
验证关键字。
productId
关键 。
description
注意到模式注释和type
验证关键字——我们在上一节中介绍了这两个。
required
验证关键字productId
列表。
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/product.schema.json",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"productId": {
"description": "The unique identifier for a product",
"type": "integer"
}
},
"required": [ "productId" ]
}
productName
是描述产品的字符串值。由于没有名称的产品并不多,因此它也是必需的。required
验证关键字是一个字符串数组,我们可以根据需要记录多个键;我们现在包括productName
.productId
和 之间并没有真正的区别productName
——为了完整起见,我们将两者都包括在内,因为计算机通常关注标识符,而人类通常关注名称。{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/product.schema.json",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"productId": {
"description": "The unique identifier for a product",
"type": "integer"
},
"productName": {
"description": "Name of the product",
"type": "string"
}
},
"required": [ "productId", "productName" ]
}
据店主说,没有免费的产品。
price
的常用description
模式注释和type
验证关键字添加密钥。它也包含在由required
验证关键字定义的键数组中。price
必须不是零。exclusiveMinimum
minimum
验证关键字。{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/product.schema.json",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"productId": {
"description": "The unique identifier for a product",
"type": "integer"
},
"productName": {
"description": "Name of the product",
"type": "string"
},
"price": {
"description": "The price of the product",
"type": "number",
"exclusiveMinimum": 0
}
},
"required": [ "productId", "productName", "price" ]
}
接下来,我们来到tags
关键。
店主是这么说的:
所以:
tags
密钥添加了通常的注释和关键字。type
验证关键字是array
.items
验证关键字,以便我们可以定义数组中出现的内容。在这种情况下:string
通过type
验证关键字的值。minItems
验证关键字用于确保数组中至少有一项。uniqueItems
所有项目必须彼此唯一。required
验证关键字数组中,因为它是可选的。{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/product.schema.json",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"productId": {
"description": "The unique identifier for a product",
"type": "integer"
},
"productName": {
"description": "Name of the product",
"type": "string"
},
"price": {
"description": "The price of the product",
"type": "number",
"exclusiveMinimum": 0
},
"tags": {
"description": "Tags for the product",
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}
},
"required": [ "productId", "productName", "price" ]
}
到目前为止,我们一直在处理一个非常扁平的模式——只有一个级别。本节演示嵌套数据结构。
dimensions
使用我们之前发现的概念添加密钥。由于type
验证关键字是object
我们可以使用 properties
验证关键字来定义嵌套数据结构。
为简洁起见,我们在示例中省略了description
annotation 关键字。虽然在这种情况下通常最好彻底注释,但大多数开发人员都非常熟悉结构和键名。
您会注意到required
验证关键字的范围适用于维度键而不是超出范围。
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/product.schema.json",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"productId": {
"description": "The unique identifier for a product",
"type": "integer"
},
"productName": {
"description": "Name of the product",
"type": "string"
},
"price": {
"description": "The price of the product",
"type": "number",
"exclusiveMinimum": 0
},
"tags": {
"description": "Tags for the product",
"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" ]
}
},
"required": [ "productId", "productName", "price" ]
}
到目前为止,我们的 JSON 模式已经完全独立。为了重用、可读性和可维护性等原因,在许多数据结构中共享 JSON 模式是很常见的。
对于这个例子,我们引入了一个新的 JSON Schema 资源和其中的两个属性:
minimum
前面提到的验证关键字。maximum
验证关键字。{
"$id": "https://example.com/geographical-location.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Longitude and Latitude",
"description": "A geographical coordinate on a planet (most commonly Earth).",
"required": [ "latitude", "longitude" ],
"type": "object",
"properties": {
"latitude": {
"type": "number",
"minimum": -90,
"maximum": 90
},
"longitude": {
"type": "number",
"minimum": -180,
"maximum": 180
}
}
}
接下来,我们添加对这个新模式的引用,以便可以合并它。
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/product.schema.json",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"productId": {
"description": "The unique identifier for a product",
"type": "integer"
},
"productName": {
"description": "Name of the product",
"type": "string"
},
"price": {
"description": "The price of the product",
"type": "number",
"exclusiveMinimum": 0
},
"tags": {
"description": "Tags for the product",
"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 where the product is located.",
"$ref": "https://example.com/geographical-location.schema.json"
}
},
"required": [ "productId", "productName", "price" ]
}
自从我们最早的样本数据(向上滚动到顶部)以来,我们当然已经扩展了产品的概念。让我们看一下与我们定义的 JSON Schema 匹配的数据。
{
"productId": 1,
"productName": "An ice sculpture",
"price": 12.50,
"tags": [ "cold", "ice" ],
"dimensions": {
"length": 7.0,
"width": 12.0,
"height": 9.5
},
"warehouseLocation": {
"latitude": -78.75,
"longitude": 20.4
}
}