互联网工程任务组 A. Wright,编辑
互联网草案
预期状态:信息性 H. Andrews,编辑
过期时间:2021 年 8 月 1 日
B. Hutton,编辑
2020 年 1 月 28 日

JSON 模式验证:用于 JSON 结构验证的词汇表
draft-bhutton-json-schema-validation-00

摘要

JSON 模式 (application/schema+json) 具有多种用途,其中之一是 JSON 实例验证。本文档指定了 JSON 模式词汇表,用于描述 JSON 文档的含义,为使用 JSON 数据的用户界面提供提示,并对有效文档的外观进行断言。

读者须知

本草案的议题列表可以在 <https://github.com/json-schema-org/json-schema-spec/issues> 找到。

有关更多信息,请参阅 <https://json-schema.fullstack.org.cn/>

要提供反馈,请使用此问题跟踪器,主页上列出的通信方式,或通过电子邮件联系文档编辑。

本备忘录的状态

本互联网草案完全符合 BCP 78 和 BCP 79 的规定提交。

互联网草案是互联网工程任务组 (IETF) 的工作文档。请注意,其他组也可能以互联网草案的形式分发工作文档。当前互联网草案的列表位于 https://datatracker.ietf.org/drafts/current/。

互联网草案是有效期最长为六个月的草案文档,随时可能被其他文档更新、替换或废弃。不适合将互联网草案用作参考材料或引用,除非作为“正在进行的工作”。

本互联网草案将于 2021 年 8 月 1 日过期。

版权声明

版权所有 (c) 2020 IETF 信托和被认定为文档作者的个人。保留所有权利。

本文件受 BCP 78 和 IETF 信托的《与 IETF 文档相关的法律条款》(https://trustee.ietf.org/license-info)约束,该条款在本文件发布之日生效。请仔细阅读这些文档,因为它们描述了您对本文件的权利和限制。从本文件提取的代码组件必须包含简化 BSD 许可证文本,如信托法律条款第 4.e 节中所述,并且按简化 BSD 许可证中所述的条款提供,不提供任何担保。


目录

1. 简介

JSON 模式可用于要求给定的 JSON 文档(实例)满足一定数量的标准。这些标准是通过使用本规范中描述的关键字来断言的。此外,还定义了一组关键字来帮助交互式用户界面实例生成。

本规范将使用 JSON 模式核心 规范中定义的概念、语法和术语。

2. 约定和术语

本文件中使用的关键词“必须”、“禁止”、“必需”、“应该”、“不应该”、“建议”、“可以”和“可选”应按照 RFC 2119 中的描述进行解释。

本规范使用术语“容器实例”来指代数组和对象实例。它使用术语“子实例”来指代数组元素或对象成员值。

如果数组值中的两个元素都不相等,则称这些元素是唯一的。

3. 概述

JSON 模式验证断言对实例数据的结构的约束。满足所有断言约束的实例位置将使用包含非断言信息的任何关键字进行注释,例如描述性元数据和使用提示。如果实例中的所有位置都满足所有断言约束,则称该实例对该模式有效。

每个模式对象都独立地针对其适用的每个实例位置进行评估。这极大地简化了验证器的实现要求,确保它们不需要在整个文档范围的验证过程中维护状态。

本规范定义了一组断言关键字,以及一小部分元数据关键字词汇表,可用于为 JSON 实例添加有用的信息。 第 7 节 关键字主要用作注释,但也可以选择用作断言。 第 8 节 关键字是用于处理作为 JSON 字符串嵌入的文档的注释。

4. 互操作性注意事项

4.1. 字符串实例的验证

需要注意的是,空字符 (\u0000) 在 JSON 字符串中是有效的。要验证的实例可能包含具有此字符的字符串值,无论底层编程语言是否能够处理此类数据。

4.2. 数值实例的验证

JSON 规范允许使用任意精度的数字,JSON 模式不会添加任何此类边界。这意味着 JSON 模式处理的数值实例可以任意大,也可以有任意长的十进制部分,无论底层编程语言是否能够处理此类数据。

4.3. 正则表达式

使用正则表达式或将实例值约束为正则表达式的关键字,受JSON 模式核心 规范中正则表达式的互操作性注意事项的约束。

5. 元模式

默认 JSON 模式方言元模式的当前 URI 为 <https://json-schema.fullstack.org.cn/draft/2020-12/schema>。为了方便模式作者,此元模式描述了一种方言,该方言包含本规范和 JSON 模式核心规范中定义的所有词汇表,以及两个保留用于过渡期的前关键字。下面每个部分都给出了各个词汇表和词汇表元模式的 URI。某些词汇表是可选的,这将在相关部分详细解释。

为了更正错误,可以在规范草案之间发布更新的词汇表和元模式 URI。实现应考虑在此规范草案之后和下一个草案之前发布的日期后的 URI,以指示与此处列出的 URI 相同的语法和语义。

6. 结构验证的词汇表

模式中的验证关键字对实例的成功验证施加要求。这些关键字都是断言,没有任何注释行为。

不使用 "$vocabulary" 的元模式应被认为需要此词汇表,就好像其 URI 存在并且值为 true 一样。

此词汇表的当前 URI(称为验证词汇表)为:<https://json-schema.fullstack.org.cn/draft/2020-12/vocab/validation>。

相应元模式的当前 URI 为:<https://json-schema.fullstack.org.cn/draft/2020-12/meta/validation>

6.1. 任何实例类型的验证关键字

6.1.1. type

此关键字的值必须是字符串或数组。如果它是一个数组,则数组的元素必须是字符串,并且必须是唯一的。

字符串值必须是六种基本类型之一(“null”、“boolean”、“object”、“array”、“number”或“string”),或“integer”,它与任何分数部分为零的数字匹配。

实例仅在实例属于此关键字列出的任何集合中时才有效。

6.1.2. enum

此关键字的值必须是一个数组。此数组应至少包含一个元素。数组中的元素应是唯一的。

如果实例的值等于此关键字数组值中的一个元素,则实例可以成功针对此关键字验证。

数组中的元素可以是任何类型,包括 null。

6.1.3. const

此关键字的值可以是任何类型,包括 null。

使用此关键字在功能上等效于具有单个值的“enum”

如果实例的值等于关键字的值,则实例可以成功针对此关键字验证。

6.2. 数值实例(数字和整数)的验证关键字

6.2.1. multipleOf

“multipleOf” 的值必须是严格大于 0 的数字。

仅当用此关键字的值进行除法运算的结果为整数时,数值实例才有效。

6.2.2. maximum

“maximum” 的值必须是一个数字,代表数值实例的包含上限。

如果实例是一个数字,则此关键字仅在实例小于或等于“最大值”时才验证。

6.2.3. exclusiveMaximum

“exclusiveMaximum”的值必须是一个数字,表示数值实例的独占上限。

如果实例是一个数字,则实例仅在它的值严格小于(不等于)“exclusiveMaximum”时才有效。

6.2.4. minimum

“minimum”的值必须是一个数字,表示数值实例的包含下限。

如果实例是一个数字,则此关键字仅在实例大于或等于“minimum”时才验证。

6.2.5. exclusiveMinimum

“exclusiveMinimum”的值必须是一个数字,表示数值实例的独占下限。

如果实例是一个数字,则实例仅在它的值严格大于(不等于)“exclusiveMinimum”时才有效。

6.3. 字符串的验证关键字

6.3.1. maxLength

此关键字的值必须是一个非负整数。

如果字符串实例的长度小于或等于此关键字的值,则该实例相对于此关键字有效。

字符串实例的长度定义为其字符的数量,如 RFC 8259 中所定义。

6.3.2. minLength

此关键字的值必须是一个非负整数。

如果字符串实例的长度大于或等于此关键字的值,则该实例相对于此关键字有效。

字符串实例的长度定义为其字符的数量,如 RFC 8259 中所定义。

省略此关键字与值为 0 的行为相同。

6.3.3. pattern

此关键字的值必须是一个字符串。此字符串应根据 ECMA-262 正则表达式方言,是一个有效的正则表达式。

如果正则表达式成功匹配实例,则字符串实例被视为有效。回想一下:正则表达式不会隐式地锚定。

6.4. 数组的验证关键字

6.4.1. maxItems

此关键字的值必须是一个非负整数。

如果数组实例的大小小于或等于此关键字的值,则该实例相对于“maxItems”有效。

6.4.2. minItems

此关键字的值必须是一个非负整数。

如果数组实例的大小大于或等于此关键字的值,则该实例相对于“minItems”有效。

省略此关键字与值为 0 的行为相同。

6.4.3. uniqueItems

此关键字的值必须是一个布尔值。

如果此关键字的布尔值为 false,则实例验证成功。如果它的布尔值为 true,则如果实例的所有元素都唯一,则该实例验证成功。

省略此关键字与值为 false 的行为相同。

6.4.4. maxContains

此关键字的值必须是一个非负整数。

如果在同一个模式对象中没有“contains”,则此关键字没有效果。

实例数组相对于“maxContains”有两种有效的验证方式,具体取决于相邻 "contains" 关键字的注释结果的形式。第一种方式是,如果注释结果是一个数组,并且该数组的长度小于或等于“maxContains”的值。第二种方式是,如果注释结果是布尔值“true”,并且实例数组的长度小于或等于“maxContains”的值。

6.4.5. minContains

此关键字的值必须是一个非负整数。

如果在同一个模式对象中没有“contains”,则此关键字没有效果。

实例数组相对于“minContains”有两种有效的验证方式,具体取决于相邻 "contains" 关键字的注释结果的形式。第一种方式是,如果注释结果是一个数组,并且该数组的长度大于或等于“minContains”的值。第二种方式是,如果注释结果是布尔值“true”,并且实例数组的长度大于或等于“minContains”的值。

允许值为 0,但仅在设置从 0 到“maxContains”值的出现次数范围时才有用。值为 0 且没有“maxContains”会导致“contains”始终通过验证。

省略此关键字与值为 1 的行为相同。

6.5. 对象的验证关键字

6.5.1. maxProperties

此关键字的值必须是一个非负整数。

如果对象实例的属性数量小于或等于此关键字的值,则该实例相对于“maxProperties”有效。

6.5.2. minProperties

此关键字的值必须是一个非负整数。

如果对象实例的属性数量大于或等于此关键字的值,则该实例相对于“minProperties”有效。

省略此关键字与值为 0 的行为相同。

6.5.3. required

此关键字的值必须是一个数组。此数组的元素(如果有)必须是字符串,并且必须是唯一的。

如果数组中的每一项都是实例中属性的名称,则对象实例相对于此关键字有效。

省略此关键字与空数组的行为相同。

6.5.4. dependentRequired

此关键字的值必须是一个对象。此对象中的属性(如果有)必须是数组。每个数组中的元素(如果有)必须是字符串,并且必须是唯一的。

此关键字指定如果存在特定其他属性,则需要哪些属性。它们的要求取决于其他属性的存在。

如果对于在实例中同时出现以及作为此关键字的值中的名称出现的每个名称,相应数组中的每一项也是实例中属性的名称,则验证成功。

省略此关键字与空对象的行为相同。

7. 使用“format”的语义内容词汇表

7.1. 序言

仅结构验证可能不足以让应用程序正确利用某些值。“format”注释关键字的定义允许模式作者传达对由权威资源(无论是 RFC 还是其他外部规范)准确描述的一组固定值的语义信息。

此关键字的值称为格式属性。它必须是一个字符串。格式属性通常只能验证给定的一组实例类型。如果要验证的实例的类型不在此集合中,则此格式属性和实例的验证应成功。本节中定义的所有格式属性都适用于字符串,但可以指定格式属性以应用于 核心 JSON 模式 中定义的数据模型中定义的任何实例类型。 [CREF1]请注意,此规范中的“type”关键字定义了“integer”类型,它不是数据模型的一部分。因此,格式属性可以限制为数字,但不能专门限制为整数。但是,数值格式可以与“type”关键字一起使用,其值为“integer”,或者可以明确定义为如果数字不是整数,则始终通过验证,这与仅应用于整数产生的行为基本相同。

此词汇表的当前 URI,称为格式注释词汇表,是:<https://json-schema.fullstack.org.cn/draft/2020-12/vocab/format-annotation>。相应元模式的当前 URI 是:<https://json-schema.fullstack.org.cn/draft/2020-12/meta/format-annotation>。实现对该词汇表的支持是必需的。

除了格式注释词汇表之外,还有一个用于自定义元模式的辅助词汇表,它将“format”定义为断言。格式断言词汇表的 URI 是:<https://json-schema.fullstack.org.cn/draft/2020-12/vocab/format-assertion>。相应元模式的当前 URI 是:<https://json-schema.fullstack.org.cn/draft/2020-12/meta/format-assertion>。实现对格式断言词汇表的支持是可选的。

指定格式注释和格式断言词汇表的功能等效于仅指定格式断言词汇表,因为它的要求是格式注释词汇表要求的超集。

7.2. 实现要求

“format”关键字按引用的词汇表的定义工作。

7.2.1. 格式注释词汇表

如果实现支持注释收集,则必须将格式的值作为注释收集。这在模式验证不可用或不足时,能够进行应用程序级别的验证。

实现仍然可以将“format”作为断言和注释来处理,并尝试验证值是否符合指定的语义。实现必须提供选项来启用和禁用此类评估,并且必须默认禁用。实现应记录其对这种验证的支持级别。 [CREF2]指定格式注释词汇表并在实现中启用验证不应被视为等同于指定格式断言词汇表,因为如果未指定格式断言词汇表,则不强制要求实现提供完整的验证支持。

当实现配置为断言行为时,它: [CREF3]这与实现的当前现实相匹配,这些实现提供了广泛的验证级别,包括对某些或所有格式属性的验证,或者根本没有验证。它还旨在鼓励仅依赖于注释行为并在应用程序中执行语义验证,这是推荐的最佳实践。

7.2.2. 格式断言词汇表

当格式断言词汇表以值为 true 的方式声明时,实现必须为本规范定义的所有格式提供完整的验证支持。无法提供完整验证支持的实现必须拒绝处理模式。

支持格式断言词汇表的实现: [CREF4]期望对于日期时间等简单格式,语法验证将是彻底的。对于电子邮件地址等复杂格式,它是各种标准和众多调整的集合,随着时间的推移,具有模糊或过时的规则,这些规则可能受到使用该值的应用程序的限制,最小验证就足够了。例如,不包含“@”的实例字符串显然不是有效的电子邮件地址,并且包含 7 位 ASCII 之外的字符的“电子邮件”或“主机名”同样明显无效。

由于许多属性的复杂性,对格式属性的最小验证要求是有意地含糊和宽松的。请特别注意,该要求仅限于语法检查;不应期望实现发送电子邮件,尝试连接到 URL,或以其他方式检查由格式实例标识的实体是否存在。

建议实现对每种格式使用通用的解析库,或使用众所周知的正则表达式。实现应清楚地记录如何以及在多大程度上验证每个格式属性。

标准核心和验证元模式在它的“$vocabulary”关键字中包含这个词汇表,值为 false,因为默认情况下,实现不需要将此关键字作为断言进行支持。使用值为 true 的格式词汇表支持意味着代码大小会显著增加,并且在某些情况下会增加执行时间,因此并非所有实现都适用。

7.2.3. 自定义格式属性

实现可以支持自定义格式属性。除非各方之间达成一致,否则模式作者不应该期望对等实现支持此类自定义格式属性。实现不得拒绝收集未知格式作为注释。当指定了格式断言词汇表时,实现遇到未知格式时必须失败。

词汇表不支持专门声明关键字的不同值集。由于这个限制,以及历史上这个关键字的实现不一致,建议在自定义词汇表中定义额外的关键字,而不是额外的格式属性,如果需要互操作性。

7.3. 定义的格式

7.3.1. 日期、时间和持续时间

这些属性适用于字符串实例。

日期和时间格式名称源自 RFC 3339,第 5.6 节。持续时间格式来自 RFC 3339 附录 A 中给出的 ISO 8601 ABNF。

支持格式的实现应该实现对以下属性的支持

date-time
如果字符串实例根据“date-time”生成规则是有效的表示形式,则它对该属性有效。
date
如果字符串实例根据“full-date”生成规则是有效的表示形式,则它对该属性有效。
time
如果字符串实例根据“full-time”生成规则是有效的表示形式,则它对该属性有效。
duration
如果字符串实例根据“duration”生成规则是有效的表示形式,则它对该属性有效。

实现可以支持使用 RFC 中定义的其他生成规则名称的其他属性。如果实现了“full-date”或“full-time”,则必须实现相应的短格式(分别为“date”或“time”),并且必须行为相同。实现不应定义名称与 RFC 3339 生成规则匹配的扩展属性,除非它根据该生成规则的规则进行验证。 [CREF5]目前还没有关于支持所有 RFC 3339 格式的共识,因此这种保留命名空间的方法将鼓励试验,而不会承诺使用整个集合。格式实现要求要么变得更加灵活,要么这些属性可能会被提升为完全指定的属性或被删除。

7.3.2. 电子邮件地址

这些属性适用于字符串实例。

如果字符串实例是有效的 Internet 电子邮件地址,如下所示,则它对这些属性有效

email
RFC 5321,第 4.1.2 节 中的“Mailbox”ABNF 规则所定义。
idn-email
RFC 6531,第 3.3 节 中扩展的“Mailbox”ABNF 规则所定义。

请注意,所有对“email”属性有效的字符串也对“idn-email”属性有效。

7.3.3. 主机名

这些属性适用于字符串实例。

如果字符串实例是 Internet 主机名的有效表示形式,如下所示,则它对这些属性有效

hostname
RFC 1123,第 2.1 节 所定义,包括使用 RFC 5891,第 4.4 节 中指定的 Punycode 算法生成的主机名。
idn-hostname
如 RFC 1123 中定义的 hostname,或 RFC 5890,第 2.3.2.3 节 中定义的国际化主机名。

请注意,所有对“hostname”属性有效的字符串也对“idn-hostname”属性有效。

7.3.4. IP 地址

这些属性适用于字符串实例。

如果字符串实例是 IP 地址的有效表示形式,如下所示,则它对这些属性有效

ipv4
根据 RFC 2673,第 3.2 节 中定义的“dotted-quad”ABNF 语法定义的 IPv4 地址。
ipv6
RFC 4291,第 2.2 节 中定义的 IPv6 地址。

7.3.5. 资源标识符

这些属性适用于字符串实例。

uri
如果字符串实例是有效的 URI,根据 [RFC3986],则它对该属性有效。
uri-reference
如果字符串实例是有效的 URI 参考(URI 或相对参考),根据 [RFC3986],则它对该属性有效。
iri
如果字符串实例是有效的 IRI,根据 [RFC3987],则它对该属性有效。
iri-reference
如果字符串实例是有效的 IRI 参考(IRI 或相对参考),根据 [RFC3987],则它对该属性有效。
uuid
如果字符串实例是 UUID 的有效字符串表示形式,根据 [RFC4122],则它对该属性有效。

请注意,所有有效的 URI 都是有效的 IRI,所有有效的 URI 参考也是有效的 IRI 参考。

还要注意,“uuid”格式用于普通 UUID,而不是 URN 中的 UUID。例如“f81d4fae-7dec-11d0-a765-00a0c91e6bf6”。对于作为 URN 的 UUID,使用“uri”格式,使用“pattern”正则表达式“^urn:uuid:”来表示 URI 方案和 URN 命名空间。

7.3.6. uri-template

此属性适用于字符串实例。

如果字符串实例是有效的 URI 模板(任何级别),根据 [RFC6570],则它对该属性有效。

请注意,URI 模板可用于 IRI;没有单独的 IRI 模板规范。

7.3.7. JSON 指针

这些属性适用于字符串实例。

json-pointer
如果字符串实例是 JSON 指针的有效 JSON 字符串表示形式,根据 RFC 6901,第 5 节,则它对该属性有效。
relative-json-pointer
如果字符串实例是有效的 相对 JSON 指针,则它对该属性有效。

为了允许使用绝对和相对 JSON 指针,使用“anyOf”或“oneOf”来表示对两种格式的支持。

7.3.8. regex

此属性适用于字符串实例。

正则表达式,应该根据 ECMA-262 正则表达式方言有效。

验证格式的实现必须至少接受本规范“正则表达式”部分中定义的 ECMA-262 的子集,并且应该接受所有有效的 ECMA-262 表达式。

8. 字符串编码数据内容的词汇表

8.1. 序言

本节中定义的注释表明实例包含在 JSON 字符串中编码的非 JSON 数据。

这些属性提供了解释 JSON 数据作为富媒体文档所需的附加信息。它们描述了内容的类型、内容的编码方式和/或内容的验证方式。它们不充当验证断言;格式错误的字符串编码文档不应导致包含的实例被认为无效。

不使用 "$vocabulary" 的元模式应被认为需要此词汇表,就好像其 URI 存在并且值为 true 一样。

此词汇表(称为内容词汇表)的当前 URI 为:<https://json-schema.fullstack.org.cn/draft/2020-12/vocab/content>。

相应元模式的当前 URI 为:<https://json-schema.fullstack.org.cn/draft/2020-12/meta/content>.

8.2. 实现要求

出于安全和性能方面的考虑,以及可能的內容类型的开放性,实现默认情况下不应自动解码、解析和/或验证字符串内容。这也支持将嵌入式文档用于与处理包含文档的消费者不同的消费者进行处理的用例。

本节中的所有关键字仅适用于字符串,并且对其他数据类型没有影响。

实现可以提供自动解码、解析和/或验证字符串内容的功能。但是,它不应默认执行这些操作,并且必须为每个字符串编码的文档提供单独的验证结果,独立于包含的文档。此过程应等同于完全评估实例以使其与原始模式匹配,然后使用注释来解码、解析和/或验证每个字符串编码的文档。 [CREF6]目前,执行和返回解析数据和/或验证结果的自动解码、解析和验证功能的具体机制尚未指定。如果此功能被证明很受欢迎,则可以在将来的草案中对其进行更详细的说明。

另请参阅 安全注意事项 部分,了解根据这些关键字自动处理实例字符串可能引入的漏洞。

8.3. contentEncoding

如果实例值是字符串,则此属性定义字符串应解释为二进制数据,并使用此属性命名的编码进行解码。

RFC 4648 中列出了指示几种变体的 base 16、32 和 64 编码的可能值。此外,RFC 2045 的第 6.7 节和第 6.8 节提供了 MIME 中使用的编码。由于“base64”在两个 RFC 中都有定义,因此应假设来自 RFC 4648 的定义,除非字符串专门用于 MIME 上下文。请注意,所有这些编码都会生成仅包含 7 位 ASCII 字符的字符串。因此,此关键字对于包含该范围之外的字符的字符串没有意义。

如果此关键字不存在,但“contentMediaType”存在,则表示编码是身份编码,这意味着不需要进行转换即可在 UTF-8 字符串中表示内容。

此属性的值必须是字符串。

8.4. contentMediaType

如果实例是字符串,则此属性表示字符串内容的媒体类型。如果存在“contentEncoding”,则此属性描述解码后的字符串。

此属性的值必须是字符串,并且必须是媒体类型,如 RFC 2046 中所定义。

8.5. contentSchema

如果实例是字符串,并且如果存在“contentMediaType”,则此属性包含描述字符串结构的模式。

此关键字可与任何可以映射到 JSON Schema 数据模型的媒体类型一起使用。

此属性的值必须是有效的 JSON 模式。如果“contentMediaType”不存在,则应忽略它。

8.6. 示例

以下是一个示例模式,说明了“contentEncoding”和“contentMediaType”的使用

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

                    

此模式描述的实例应为字符串,其值应可解释为 base64 编码的 PNG 图像。

另一个示例

{
    "type": "string",
    "contentMediaType": "text/html"
}

                    

此模式描述的实例应为包含 HTML 的字符串,使用 JSON 字符串解码成的任何字符集。根据 RFC 8259 的第 8.1 节,在完全封闭的系统之外,这必须是 UTF-8。

此示例描述了一个使用 HMAC SHA-256 算法进行 MAC 的 JWT,并且要求其声明集中包含“iss”和“exp”字段。

{
    "type": "string",
    "contentMediaType": "application/jwt",
    "contentSchema": {
        "type": "array",
        "minItems": 2,
        "prefixItems": [
            {
                "const": {
                    "typ": "JWT",
                    "alg": "HS256"
                }
            },
            {
                "type": "object",
                "required": ["iss", "exp"],
                "properties": {
                    "iss": {"type": "string"},
                    "exp": {"type": "integer"}
                }
            }
        ]
    }
}
                    

请注意,“contentEncoding”没有出现。虽然“application/jwt”媒体类型使用 base64url 编码,但这是由媒体类型定义的,媒体类型决定了 JWT 字符串如何被解码为两个 JSON 数据结构的列表:第一个是标头,第二个是负载。由于 JWT 媒体类型确保 JWT 可以表示为 JSON 字符串,因此无需进一步编码或解码。

9. 用于基本元数据注释的词汇表

这些通用注释关键字提供用于文档和用户界面显示目的的常用信息。它们并非旨在构成一组全面的功能。相反,可以为更复杂的基于注释的应用程序定义其他词汇表。

不使用 "$vocabulary" 的元模式应被认为需要此词汇表,就好像其 URI 存在并且值为 true 一样。

此词汇表的当前 URI(称为元数据词汇表)为:<https://json-schema.fullstack.org.cn/draft/2020-12/vocab/meta-data>。

相应元模式的当前 URI 为:<https://json-schema.fullstack.org.cn/draft/2020-12/meta/meta-data>

9.1. "title" 和 "description"

这两个关键字的值必须是字符串。

这两个关键字都可以用来用有关此用户界面生成的数据的信息来装饰用户界面。标题最好简短,而描述将提供有关此模式描述的实例目的的说明。

9.2. "default"

此关键字的值没有任何限制。当此关键字的多个出现适用于单个子实例时,实现应该删除重复项。

此关键字可用于提供与特定模式关联的默认 JSON 值。建议默认值应针对关联模式有效。

9.3. "deprecated"

此关键字的值必须是布尔值。当此关键字的多个出现适用于单个子实例时,应用程序应该考虑实例位置已弃用,如果任何出现指定 true 值。

如果 "deprecated" 的值为布尔值 true,则表示应用程序应该避免使用声明的属性。它可能意味着该属性将在将来被删除。

包含值为 true 的 "deprecated" 的根模式表明,将来可能删除正在描述的整个资源。

"deprecated" 关键字适用于包含该关键字的模式对象成功应用的每个实例位置。这会导致以下情况:即使包含的数组或对象未弃用,每个数组项或对象属性也可能被弃用。

省略此关键字与值为 false 的行为相同。

9.4. "readOnly" 和 "writeOnly"

这些关键字的值必须是布尔值。当这些关键字的多个出现适用于单个子实例时,如果任何出现指定 true 值,则结果行为应该与 true 值相同,否则应该与 false 值相同。

如果 "readOnly" 的值为布尔值 true,则表示实例的值完全由拥有机构管理,应用程序尝试修改此属性的值预计将被该拥有机构忽略或拒绝。

如果整个文档被标记为 "readOnly",则该实例文档在发送到拥有机构时可能会被忽略,或者可能会导致错误,具体取决于机构的决定。

如果 "writeOnly" 的值为布尔值 true,则表示在从拥有机构检索实例时,该值永远不会存在。它可以在发送到拥有机构以更新或创建文档(或它所代表的资源)时存在,但它不会包含在任何更新或新创建的实例版本中。

如果整个文档被标记为 "writeOnly",则该实例文档可能会作为某种空白文档返回,或者在检索时可能会产生错误,或者检索请求可能会被忽略,具体取决于机构的决定。

例如,"readOnly" 用于将数据库生成的序列号标记为只读,而 "writeOnly" 用于将密码输入字段标记为只读。

这些关键字可用于辅助用户界面实例生成。特别地,应用程序可以选择使用一个部件,该部件在写入时隐藏输入值。

省略这些关键字的行为与 false 的值相同。

9.5. "examples"

此关键字的值必须是数组。对数组中的值没有限制。当此关键字的多个出现适用于单个子实例时,实现必须提供所有值的扁平数组,而不是数组的数组。

此关键字可用于提供与特定模式关联的示例 JSON 值,以说明用法。建议这些值应针对关联模式有效。

实现可以使用 "default" 的值(如果存在)作为附加示例。如果 "examples" 缺失,则 "default" 仍然可以使用这种方式。

10. 安全注意事项

JSON 模式验证定义了 JSON 模式核心词汇,并涉及其中列出的所有安全注意事项。

JSON 模式验证允许使用正则表达式,正则表达式有许多不同的(通常不兼容的)实现。一些实现允许嵌入任意代码,这超出了 JSON 模式的范围,并且绝对不允许。正则表达式也经常可以被设计为计算起来非常昂贵(使用所谓的“灾难性回溯”),从而导致拒绝服务攻击。

支持根据 "contentEncoding" 和/或 "contentMediaType" 验证或以其他方式评估实例字符串数据的实现,有风险根据误导性信息以不安全的方式评估数据。应用程序可以通过仅在建立模式和实例之间的关系(例如,它们共享相同的权限)时执行此类处理来降低此风险。

处理媒体类型或编码受该媒体类型或编码的安全注意事项的约束。例如,在处理 JSON 字符串中编码的 JavaScript 或 ECMAScript 时,RFC 4329 脚本媒体类型 的安全注意事项适用。

11. 参考文献

11.1. 规范性参考文献

[ecma262] "ECMA-262,第 11 版规范",2020 年 6 月。
[json-schema] Wright, A.Andrews, H.Hutton, B.G. Dennis,"JSON 模式:用于描述 JSON 文档的媒体类型",互联网草案 draft-bhutton-json-schema-00,2020 年 12 月。
[relative-json-pointer] Luff, G.Andrews, H.B. Hutton,"相对 JSON 指针",互联网草案 draft-handrews-relative-json-pointer-01,2020 年 12 月。
[RFC1123] Braden, R.,"互联网主机要求 - 应用和支持",STD 3,RFC 1123,DOI 10.17487/RFC1123,1989 年 10 月。
[RFC2045] Freed, N.N. Borenstein,"多用途互联网邮件扩展 (MIME) 第一部分:互联网消息正文格式",RFC 2045,DOI 10.17487/RFC2045,1996 年 11 月。
[RFC2046] Freed, N.N. Borenstein,"多用途互联网邮件扩展 (MIME) 第二部分:媒体类型",RFC 2046,DOI 10.17487/RFC2046,1996 年 11 月。
[RFC2119] Bradner, S.,"用于 RFC 中的关键字以指示要求级别",BCP 14,RFC 2119,DOI 10.17487/RFC2119,1997 年 3 月。
[RFC2673] Crawford, M.,"域名系统中的二进制标签",RFC 2673,DOI 10.17487/RFC2673,1999 年 8 月。
[RFC3339] Klyne, G.C. Newman,"互联网上的日期和时间:时间戳",RFC 3339,DOI 10.17487/RFC3339,2002 年 7 月。
[RFC3986] Berners-Lee, T.Fielding, R.L. Masinter,"统一资源标识符 (URI):通用语法",STD 66,RFC 3986,DOI 10.17487/RFC3986,2005 年 1 月。
[RFC3987] Duerst, M.M. Suignard,"国际化资源标识符 (IRI)",RFC 3987,DOI 10.17487/RFC3987,2005 年 1 月。
[RFC4122] Leach, P.Mealling, M.R. Salz,"通用唯一标识符 (UUID) URN 命名空间",RFC 4122,DOI 10.17487/RFC4122,2005 年 7 月。
[RFC4291] Hinden, R.S. Deering,"IPv6 地址架构",RFC 4291,DOI 10.17487/RFC4291,2006 年 2 月。
[RFC4648] Josefsson, S.,"Base16、Base32 和 Base64 数据编码",RFC 4648,DOI 10.17487/RFC4648,2006 年 10 月。
[RFC5321] Klensin, J.,"简单邮件传输协议",RFC 5321,DOI 10.17487/RFC5321,2008 年 10 月。
[RFC5890] Klensin, J.,"应用程序的国际化域名 (IDNA):定义和文档框架",RFC 5890,DOI 10.17487/RFC5890,2010 年 8 月。
[RFC5891] Klensin, J.,"应用程序中的国际化域名 (IDNA):协议",RFC 5891,DOI 10.17487/RFC5891,2010 年 8 月。
[RFC6531] Yao, J.W. Mao,"国际化电子邮件的 SMTP 扩展",RFC 6531,DOI 10.17487/RFC6531,2012 年 2 月。
[RFC6570] Gregorio, J.Fielding, R.Hadley, M.Nottingham, M.D. Orchard,"URI 模板",RFC 6570,DOI 10.17487/RFC6570,2012 年 3 月。
[RFC6901] Bryan, P.Zyp, K.M. Nottingham,"JavaScript 对象表示法 (JSON) 指针",RFC 6901,DOI 10.17487/RFC6901,2013 年 4 月。
[RFC8259] Bray, T.,"JavaScript 对象表示法 (JSON) 数据交换格式",STD 90,RFC 8259,DOI 10.17487/RFC8259,2017 年 12 月。

11.2. 信息性参考文献

[RFC4329] Hoehrmann, B.,"脚本媒体类型",RFC 4329,DOI 10.17487/RFC4329,2006 年 4 月。

附录 A. 从验证移至核心的关键字

从本草案开始,一些关键字已从本文档移至 核心规范,在某些情况下进行了重命名或其他更改。这影响了以下以前的验证关键字

"definitions"
重命名为 "$defs" 以匹配 "$ref" 并缩短输入。模式词汇作者不应定义行为不同的 "definitions" 关键字,以避免使仍然使用旧名称的模式失效。虽然本文件引用的单一词汇元模式中不存在 "definitions",但它仍然存在于默认元模式中,实现应该假设 "$defs" 和 "definitions" 在使用该元模式时具有相同的行为。
"allOf", "anyOf", "oneOf", "not", "if", "then", "else", "items", "additionalItems", "contains", "propertyNames", "properties", "patternProperties", "additionalProperties"
所有这些关键字都将子模式应用于实例,并组合其结果,而没有断言其自身的任何条件。没有断言关键字,这些应用器只能通过使用 false 布尔模式或通过反转 true 布尔模式(或等效模式对象)的结果来导致断言失败。因此,最好将它们定义为一个通用机制,验证、超模式和扩展词汇可以基于它。
"dependencies"
这个关键字有两种不同的行为模式,这使得它在实现和推理方面相对具有挑战性。模式形式已移至核心并重命名为“dependentSchemas”,作为应用词汇表的一部分。它类似于“properties”,不同之处在于它不是将其子模式应用于属性值,而是将其应用于包含该属性的对象。属性名称数组形式保留在此处并重命名为“dependentRequired”,因为它是一种断言,它是条件使用“required”断言关键字的快捷方式。

附录 B. 致谢

感谢 Gary Court、Francis Galiegue、Kris Zyp 和 Geraint Luff 对 JSON Schema 初始草案的贡献。

感谢 Jason Desrosiers、Daniel Perrett、Erik Wilde、Evgeny Poberezkin、Brad Bowman、Gowry Sankar、Donald Pipowitch、Dave Finlay、Denis Laxalde、Phil Sturgeon、Shawn Silverman 和 Karen Etheridge 对该文档的贡献和补丁。

附录 C. 变更日志

[CREF7]此部分在离开 Internet-Draft 状态之前将被删除。

draft-bhutton-json-schema-validation-00

draft-handrews-json-schema-validation-02

draft-handrews-json-schema-validation-01

draft-handrews-json-schema-validation-00

draft-wright-json-schema-validation-01

draft-wright-json-schema-validation-00

draft-fge-json-schema-validation-00

作者地址

Austin Wright (编辑) EMail: [email protected]
Henry Andrews (编辑) EMail: [email protected]
Ben Hutton (编辑) EMail: [email protected] URI: https://jsonschema.dev