2022 年 1 月 21 日,星期五 ·9分钟阅读

JSON Schema 入门:5 分钟速成

如果您之前从未听说过 JSON Schema,那么您来对地方了。如果您对使用 JSON Schema 很自信,这篇文章也对您有所帮助,您可能仍然会学到一些新东西。

读完这篇文章后,您将

  • 理解 JSON Schema 是什么
  • 了解 JSON Schema 的功能
  • 理解一些关于 JSON Schema 的关键术语
  • 了解 JSON Schema 工作原理的一些基础知识
  • 超越那些拥有多年 JSON Schema 经验的人(希望如此)

虽然这是一篇技术介绍,但我们今天不会讲任何代码。但我们会为您提供几乎所有编程语言实现的列表。

JSON 是什么?

主要而言,JSON Schema 用于验证数据。JSON Schema 可以验证的类型是使用 JSON 编码的数据。

JSON 代表 JavaScript 对象符号,是 Javascript 的一个子集。JSON 既可读懂又可由机器解读,这使得它成为数据交换的流行格式选择。

JSON Schema 是指该项目名称,也是定义所需验证的工件(一个 JSON Schema)。验证规则是通过定义针对 JSON 数据的约束来表达的。

您要验证的 JSON 数据称为“JSON 实例”。

JSON Schema

JSON Schema 项目位于 GitHub 上,组织名称为“json-schema-org”。它由多个 git 仓库组成,用于跟踪更改并支持规范和支持资源的协作。

JSON Schema 规范由技术规范文档组成,目前通过互联网工程任务组 (IETF) 正式发布,作为一系列“个人草案”。“个人草案”是 IETF 工作组发布的文档类别。

JSON Schema 文档本身是用 JSON 编写的。用 JSON 编写意味着几乎每种编程语言都可以读取它,这使得它成为一种可互操作的验证解决方案。它也可以使用其他格式编写,这些格式会转换为 JSON,或者使用可以序列化为 JSON 的代码编写。

一个 JSON Schema(文档)

我们提到 JSON Schema 本身就是 JSON。以前,JSON 的根级别必须是对象或数组,但现在,它也可以是任何允许的值。

JSON Schema 可以是对象或布尔值。布尔值形式的结果与验证断言结果相同。对象形式允许使用关键字和值来表达验证约束。

JSON Schema 是基于约束的,这意味着任何未定义(或约束)的内容都是允许的,被视为有效的。

Schema 允许布尔值可能看起来很奇怪,但我们稍后会探讨为什么这很有用。现在,让我们看一下我们的第一个 Schema 示例。

约束介绍

数据
{}
一个空对象
数据
true
一个“true”布尔值
数据
false
一个“false”布尔值
数据
{ "not": { } }
非空对象

让我们依次解释每个 Schema 并解释验证结果。

空对象 Schema 不表达任何约束。任何实例数据都将始终被视为有效。“true”布尔值 Schema 将始终断言实例数据是有效的。

如您所料,其余两个 Schema 的情况正好相反。“false”布尔值 Schema 将始终断言为 false,而“非空对象”Schema 将具有相同的结果。

not 关键字以 JSON Schema 作为其值。这些“schema 值”称为子 Schema。子 Schema 应用于实例数据,并且结果断言会被反转。正如我们现在所知,空对象 Schema 会产生“true”断言,所以反转的结果是“false”。

对象 Schema

对象 Schema 中的键是 JSON Schema 关键字。这些关键字有四类:标识符、应用器、断言和注释。一些关键字不适合这些类别,因为它们具有独特的功能。

$schema 关键字具有独特的功能。此关键字的值是一个 URI,用于标识在处理 Schema 时要使用的 JSON Schema 方言。

您可以将 JSON Schema 方言视为具有定义含义的一组关键字。在大多数情况下,您将处理的不同方言仅仅是 JSON Schema 的不同版本(或“草案”)。

最佳实践是在使用 $schema 关键字定义正在使用的 JSON Schema 方言。这样做,如果实现发现它们不支持的 JSON Schema 版本,应该会抛出错误。

如果您的 Schema 没有定义它正在使用的 JSON Schema 方言,实现可能会选择任何方言。这可能导致使用不支持该版本的实现时出现误报。

在本介绍中,我们将使用 JSON Schema 的 2020-12 版本,但您将学习的大多数内容适用于当今生产中使用的几乎所有版本。

2020-12 JSON Schema 方言 URI 是 https://json-schema.fullstack.org.cn/draft/2020-12/schema

断言

记住 JSON Schema 提供基于约束的验证,JSON Schema 定义了关键字,当应用于实例时,这些关键字会提供断言结果(通过或失败)。

“const”关键字

最简单的断言关键字是 const。值可以是任何有效的 JSON。要通过验证,数据必须与 const 的值相同。这是一个例子

schema
{ "const": 1234 }
数据
1234
符合 schema
有效 - 它完全相同
数据
"foobar"
不符合 schema
无效 - 它不相同

“type”关键字

另一个断言关键字是 type。它的值是一个字符串数组,表示允许的类型。这些类型是 JSON 定义的六种基本类型,再加上“integer”。让我们看一个例子。

schema
{ "type": ["object", "boolean", "null"] }
数据
{ "ok": "yes" }
符合 schema
有效 - 允许使用对象。
数据
true
符合 schema
有效 - 允许使用布尔值。
数据
null
符合 schema
有效 - 允许使用空值。
数据
123
不符合 schema
无效 - 不允许使用数字。
数据
"foobar"
不符合 schema
无效 - 不允许使用字符串。

这两个断言关键字适用于 JSON 中的任何类型数据,但某些断言关键字只适用于特定类型。如果关键字不适用于实例数据,则会忽略它并且不执行验证。

“required”关键字

required 是一个断言关键字,它只适用于对象。让我们通过一些示例来探讨其含义。

{ "required": ["name"] } - 我们的 JSON Schema { "name": "Bob" } - 有效 - “name”在对象中。 { "fullName": "Bob" } - 无效 - “name”在对象中缺失。 "Bob" - 有效 - required 关键字只适用于对象。 true - 有效 - 与上述相同。

这可能令人惊讶,但它允许组合逻辑上只有在特定类型数据的情况下才合理的约束。

您应该在同一个 Schema 中结合使用 type 与其他关键字,以避免类型期望不匹配。

应用器

验证从将根 Schema 应用于完整的实例文档开始。应用器关键字将子 Schema 应用于实例位置。

“properties”关键字

最常用的应用器关键字是 properties,它具有一个对象值,其中值是子 Schema。让我们看看它在实际中的应用。

schema
{ "properties": { "name": { "type": ["string"] } }}
我们的 JSON Schema
数据
{ "name": "Alice"}
符合 schema
实例具有 name,它是一个字符串
数据
{ "fullName": "Alice"}
符合 schema
实例对象没有 `name` 属性
数据
[ "name", 123 ]
符合 schema
实例不是对象,因此 `properties` 不适用

子 Schema 仅应用于实例位置,其中键与实例位置对象中的键匹配。

如果您要确保实例数据是对象,请使用 type 关键字。

如果您想确保对象拥有“name”属性,请使用required关键字。

回顾

JSON Schema 无法正常工作最常见的原因是缺少完整的必需约束。

JSON Schema 是“基于约束”的,关键字可能只适用于正确的数据类型。使用多个关键字来收紧约束,可以确保类型特定的关键字不匹配由不同的关键字处理。

识别子模式,并了解模式始终可以是布尔值,可以帮助您确认对正确适用性的假设。如果需要,始终可以单独测试子模式。

下一步/进一步阅读

希望这份关于 JSON Schema 基础知识的简短介绍能帮助您更好地阅读、推理和开发 JSON Schema。

我建议您现在使用 VSCode 来编写 JSON Schema。当文件处于 JSON 语言模式,并且$schema值被添加到根对象时,VSCode 会提供自动完成和 IntelliSense(尽管这仅限于 draft-07)。

以下是一些您可能在未来发现有用的资源:

照片由 Saad SalimUnsplash 上拍摄