互联网工程任务组 | fge. Galiegue, Ed. |
互联网草案 | |
预期状态:信息 | K. Zyp |
过期时间:2017 年 8 月 26 日 | SitePen(美国) |
G. Court | |
2013 |
JSON 模式:交互式和非交互式验证
draft-fge-json-schema-validation-00
JSON 模式 (application/schema+json) 有多种用途,其中之一是实例验证。验证过程可以是交互式的或非交互式的。例如,应用程序可以使用 JSON 模式来构建用户界面,实现交互式内容生成以及用户输入检查,或者验证从各种来源检索的数据。本规范描述了专用于验证目的的模式关键字。
本互联网草案完全符合 BCP 78 和 BCP 79 的规定。
互联网草案是互联网工程任务组 (IETF) 的工作文档。请注意,其他组也可能将工作文档作为互联网草案分发。当前互联网草案的列表位于 http://datatracker.ietf.org/drafts/current/。
互联网草案是有效期最长为六个月的草案文档,随时可能被其他文档更新、替换或废止。不适宜将互联网草案用作参考资料,也不应将其引用,除非作为“正在进行的工作”。
本互联网草案将于 2017 年 8 月 26 日过期。
版权所有 (c) 2013 IETF 信托和被识别为文档作者的人员。保留所有权利。
本文件受 BCP 78 和 IETF 信托的 IETF 文件法律条款 (http://trustee.ietf.org/license-info) 的约束,这些条款在发布本文件之日生效。请仔细阅读这些文件,因为它们描述了您对本文件的权利和限制。从本文件中提取的代码组件必须包含简化的 BSD 许可证文本,如信托法律条款第 4.e 节所述,并按简化的 BSD 许可证所述提供,不提供任何担保。
JSON 模式可用于要求给定的 JSON 文档 (实例) 满足一定数量的条件。这些条件由本规范中描述的一组关键字体现。此外,还定义了一组关键字来帮助交互式实例生成。这些也在本规范中描述。
本规范将使用 JSON 模式核心规范中定义的术语。建议读者获取一份该规范的副本。
本文件中出现的关键词“必须”、“禁止”、“必需”、“应”、“不应”、“建议”、“不建议”、“可选项”和“可选”应按 RFC 2119 [RFC2119] 中的描述进行解释。
本规范使用术语“容器实例”来指代数组和对象实例。它使用术语“子实例”来指代数组元素或对象成员值。
本规范使用术语“属性集”来指代对象的成员名称集;例如,JSON 对象 { “a”: 1, “b”: 2 } 的属性集是 [ “a”, “b” ]。
数组值中的元素如果按核心规范的定义,没有两个元素相等,则称这些元素是唯一的。
需要注意的是,空字符 (\x00) 在 JSON 字符串中是有效的。要验证的实例可以包含具有此字符的字符串值,而与底层编程语言处理此类数据的具体能力无关。
JSON 规范没有定义任何对数字值范围或精度的界限。JSON 模式也没有定义任何此类界限。这意味着 JSON 模式处理的数字实例可以任意大,或者小数部分可以任意大,而与底层编程语言处理此类数据的具体能力无关。
两个验证关键字“pattern”和“patternProperties”使用正则表达式来表达约束。这些正则表达式应根据 ECMA 262 [ecma262] 正则表达式方言有效。
此外,鉴于正则表达式构造支持方面的巨大差异,模式作者应将自己限制在以下正则表达式标记中
最后,实现禁止认为正则表达式是锚定的,无论是在开头还是结尾。这意味着,例如,“es” 匹配“expression”。
一些验证关键字只适用于一个或多个基本类型。当实例的基本类型无法通过给定关键字进行验证时,该关键字和实例的验证应成功。
本规范根据这些关键字验证的基元类型,或类型,将关键字分组到不同的部分。请注意,一些关键字验证所有实例类型。
为了验证实例,一些关键字会受到其他关键字存在 (或不存在) 的影响。在这种情况下,所有这些关键字都将被分组到同一部分。
一些关键字,如果缺失,可能被实现认为具有默认值。在这种情况下,将提及默认值。
具有验证容器实例 (数组或对象) 能力的关键字只验证实例本身,而不验证其子项 (数组项或对象属性)。但是,其中一些关键字包含的信息对于计算子项必须验证的模式至关重要。计算子项实例相关模式的算法将在单独的部分中解释。
需要注意的是,虽然数组元素只需要验证一个模式,但对象成员值可能需要验证多个模式。
“multipleOf”的值必须是 JSON 数字。此数字必须严格大于 0。
如果实例与该关键字的值相除的结果为整数,则数字实例对“multipleOf”有效。
“maximum”的值必须是 JSON 数字。“exclusiveMaximum”的值必须是布尔值。
如果存在“exclusiveMaximum”,则“maximum”也必须存在。
成功验证取决于“exclusiveMaximum”的存在和值
如果“exclusiveMaximum”不存在,可以认为它存在,布尔值为假。
“minimum” 的值必须是 JSON 数字。 “exclusiveMinimum” 的值必须是布尔值。
如果存在“exclusiveMinimum”,则“minimum” 也必须存在。
验证成功取决于“exclusiveMinimum”的存在和值。
如果“exclusiveMinimum”不存在,则可以认为它存在,且布尔值为 false。
此关键字的值必须是整数。该整数必须大于或等于 0。
如果字符串实例的长度小于或等于此关键字的值,则该实例针对此关键字有效。
字符串实例的长度定义为其字符数量,如 RFC 4627 [RFC4627] 所定义。
此关键字的值必须是整数。该整数必须大于或等于 0。
如果字符串实例的长度大于或等于此关键字的值,则该实例针对此关键字有效。
字符串实例的长度定义为其字符数量,如 RFC 4627 [RFC4627] 所定义。
如果“minLength”不存在,则可以认为它存在,且整数值为 0。
此关键字的值必须是字符串。该字符串应是有效的正则表达式,符合 ECMA 262 正则表达式语法。
如果正则表达式成功匹配实例,则字符串实例被认为有效。请注意:正则表达式不会隐式锚定。
“additionalItems” 的值必须是布尔值或对象。如果它是对象,则该对象必须是有效的 JSON Schema。
“items” 的值必须是对象或数组。如果它是对象,则该对象必须是有效的 JSON Schema。如果它是数组,则该数组的项目必须是对象,并且每个对象必须是有效的 JSON Schema。
确定数组实例关于这两个关键字的验证成功与否,如下所示。
以下示例涵盖了“additionalItems” 的布尔值为 false,而 “items” 是数组的情况,因为这是实例可能无法成功验证的唯一情况。
这是一个示例模式。
{ "items": [ {}, {}, {} ], "additionalItems": false }
使用此模式,以下实例有效。
以下实例无效。
如果任一关键字不存在,则可以认为它存在,且值为空模式。
此关键字的值必须是整数。该整数必须大于或等于 0。
如果数组实例的大小小于或等于此关键字的值,则该实例针对 “maxItems” 有效。
此关键字的值必须是整数。该整数必须大于或等于 0。
如果数组实例的大小大于或等于此关键字的值,则该实例针对 “minItems” 有效。
如果此关键字不存在,则可以认为它存在,且值为 0。
此关键字的值必须是布尔值。
如果此关键字的布尔值为 false,则实例验证成功。如果其布尔值为 true,则当所有元素都唯一时,实例验证成功。
如果不存在,则可以认为此关键字存在,且布尔值为 false。
此关键字的值必须是整数。该整数必须大于或等于 0。
如果对象实例的属性数量小于或等于此关键字的值,则该实例针对 “maxProperties” 有效。
此关键字的值必须是整数。该整数必须大于或等于 0。
如果对象实例的属性数量大于或等于此关键字的值,则该实例针对 “minProperties” 有效。
如果此关键字不存在,则可以认为它存在,且值为 0。
此关键字的值必须是数组。该数组必须至少包含一个元素。该数组的元素必须是字符串,并且必须唯一。
如果对象实例的属性集包含此关键字数组值中的所有元素,则该实例针对此关键字有效。
“additionalProperties” 的值必须是布尔值或对象。如果它是对象,则它也必须是有效的 JSON Schema。
“properties” 的值必须是对象。该对象的每个值必须是对象,并且每个对象必须是有效的 JSON Schema。
“patternProperties” 的值必须是对象。该对象的每个属性名称应是有效的正则表达式,符合 ECMA 262 正则表达式语法。该对象的每个属性值必须是对象,并且每个对象必须是有效的 JSON Schema。
对象实例针对这三个关键字的验证成功与否取决于 “additionalProperties” 的值。
如果 “properties” 或 “patternProperties” 不存在,则可以认为它们存在,且值为空对象。
如果 “additionalProperties” 不存在,则可以认为它存在,且值为空模式。
在这种情况下,实例的验证取决于 “properties” 和 “patternProperties” 的属性集。在本节中,为了方便起见,将 “patternProperties” 的属性名称称为正则表达式。
第一步是收集以下集合。
收集完这三个集合后,过程如下。
如果在执行完这两个步骤后,集合 “s” 为空,则实例的验证成功。
此模式将用作示例。
{ "properties": { "p1": {} }, "patternProperties": { "p": {}, "[0-9]": {} }, "additionalProperties": false }
这是要验证的实例。
{ "p1": true, "p2": null, "a32&o": "foobar", "": [], "fiddle": 42, "apple": "pie" }
这三个属性集是。
应用算法的两个步骤。
集合 “s” 仍然包含两个元素:"" 和 “fiddle”。因此验证失败。
此关键字的值必须是对象。该对象的每个值必须是对象或数组。
如果该值为对象,则它必须是有效的 JSON Schema。这称为模式依赖项。
如果该值为数组,则它必须至少包含一个元素。每个元素必须是字符串,并且数组中的元素必须唯一。这称为属性依赖项。
对于所有 (名称,模式) 模式依赖项对,如果实例具有此名称的属性,则它也必须针对该模式成功验证。
请注意,这是必须成功验证的实例本身,而不是与属性名称关联的值。
对于每个 (名称,属性集) 属性依赖项对,如果实例具有此名称的属性,则它也必须具有与属性集名称相同的属性。
此关键字的值必须是数组。该数组必须至少包含一个元素。数组中的元素必须唯一。
数组中的元素可以是任何类型,包括 null。
如果实例的值等于此关键字数组值中的一个元素,则该实例针对此关键字成功验证。
此关键字的值必须是字符串或数组。如果它是数组,则数组的元素必须是字符串,并且必须唯一。
字符串值必须是核心规范定义的七种基本类型之一。
如果实例的基本类型是关键字定义的类型之一,则该实例成功匹配。请注意:“number” 包含 “integer”。
此关键字的值必须是数组。该数组必须至少包含一个元素。
数组的元素必须是对象。每个对象必须是有效的 JSON Schema。
如果实例针对此关键字值定义的所有模式成功验证,则该实例针对此关键字成功验证。
此关键字的值必须是数组。该数组必须至少包含一个元素。
数组的元素必须是对象。每个对象必须是有效的 JSON Schema。
如果实例针对此关键字值定义的至少一个模式成功验证,则该实例针对此关键字成功验证。
此关键字的值必须是数组。该数组必须至少包含一个元素。
数组的元素必须是对象。每个对象必须是有效的 JSON Schema。
如果实例成功验证了此关键字的值定义的架构中的一个架构,则它成功验证了此关键字。
此关键字的值必须是对象。此对象必须是一个有效的 JSON 架构。
如果实例未能成功验证此关键字定义的架构,则它对此关键字有效。
此关键字的值必须是对象。此对象的每个成员值必须是一个有效的 JSON 架构。
此关键字本身在验证中不扮演任何角色。它的作用是为架构作者提供一个标准化位置,以便将 JSON 架构内联到更通用的架构中。
{ "type": "array", "items": { "$ref": "#/definitions/positiveInteger" }, "definitions": { "positiveInteger": { "type": "integer", "minimum": 0, "exclusiveMinimum": true } } }
例如,以下架构描述了正整数数组,其中正整数约束是 "definitions" 中的子架构。
这两个关键字的值必须是字符串。
这两个关键字都可以用于用有关此用户界面生成的数据的信息装饰用户界面。标题最好简短,而描述将提供有关此架构描述的实例目的的解释。
这两个关键字可以在根架构中使用,也可以在任何子架构中使用。
对该关键字的值没有限制。
此关键字可用于提供与特定架构相关的默认 JSON 值。建议默认值对关联架构有效。
此关键字可以在根架构中使用,也可以在任何子架构中使用。
仅结构验证可能不足以验证实例是否满足应用程序的所有要求。定义 "format" 关键字以允许对由权威资源(无论是 RFC 还是其他外部规范)准确描述的固定值子集进行可互操作的语义验证。
此关键字的值称为格式属性。它必须是字符串。格式属性通常只能验证给定的一组实例类型。如果要验证的实例的类型不在此集合中,则此格式属性和实例的验证应成功。
实现可以支持 "format" 关键字。如果他们选择这样做
实现可以添加自定义格式属性。除了双方之间的协议外,架构作者不应期望对等实现支持此关键字和/或自定义格式属性。
此属性适用于字符串实例。
如果字符串实例是 RFC 3339,第 5.6 节 [RFC3339] 中定义的有效日期表示,则它对该属性有效。
此属性适用于字符串实例。
如果字符串实例是 RFC 5322,第 3.4.1 节 [RFC5322] 中定义的有效的 Internet 电子邮件地址,则它对该属性有效。
此属性适用于字符串实例。
如果字符串实例是 RFC 1034,第 3.1 节 [RFC1034] 中定义的 Internet 主机名的有效表示,则它对该属性有效。
此属性适用于字符串实例。
如果字符串实例是 RFC 2673,第 3.2 节 [RFC2673] 中定义的“点分四元组”ABNF 语法中定义的 IPv4 地址的有效表示,则它对该属性有效。
此属性适用于字符串实例。
如果字符串实例是 RFC 2373,第 2.2 节 [RFC2373] 中定义的 IPv6 地址的有效表示,则它对该属性有效。
此属性适用于字符串实例。
如果字符串实例是根据 [RFC3986] 定义的有效 URI,则它对该属性有效。
计算子实例必须验证的架构或架构受以下因素影响
此外,重要的是,如果计算中隐含的一个或多个关键字未定义,则应将它们视为存在,并具有其默认值,这将在本节中回顾。
子实例的定义特征是它在数组中的索引。回顾:数组索引从 0 开始。
此计算中的两个隐含关键字是 "items" 和 "additionalItems"。
如果任一关键字不存在,则认为它存在,值为空架构。此外,"additionalItems" 的布尔值 true 被认为等同于空架构。
如果 items 是架构,则子实例必须针对此架构验证,无论其索引是什么,无论 "additionalItems" 的值是什么。
在这种情况下,架构取决于索引
定义特征是子项的属性名称。
此计算中隐含的三个关键字是 "properties"、"patternProperties" 和 "additionalProperties"。
如果 "properties" 或 "patternProperties" 不存在,则认为它们存在,值为空对象。
如果 "additionalProperties" 不存在,则认为它存在,值为空架构。此外,布尔值 true 被认为等同于空架构。
以下计算使用以下名称
如果集 "p" 包含值 "m",则 "properties" 中的相应架构将添加到 "s" 中。
对于 "pp" 中的每个正则表达式,如果它成功匹配 "m",则 "patternProperties" 中的相应架构将添加到 "s" 中。
仅当此时 "s" 为空时,才会将 "additionalProperties" 定义的架构添加到 "s" 中。
JSON 架构验证没有比 JSON 架构核心规范中定义的任何其他安全注意事项。
本规范对 IANA 没有影响。
[RFC2119] | Bradner, S.,"RFC 中用于指示要求级别的关键词",BCP 14,RFC 2119,DOI 10.17487/RFC2119,1997 年 3 月。 |
[RFC1034] | Mockapetris, P.,"域名 - 概念和设施",STD 13,RFC 1034,DOI 10.17487/RFC1034,1987 年 11 月。 |
[RFC2373] | Hinden, R. 和 S. Deering,"IPv6 地址架构",RFC 2373,DOI 10.17487/RFC2373,1998 年 7 月。 |
[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 月。 |
[RFC4627] | Crockford, D.,"JavaScript 对象表示法 (JSON) 的 application/json 媒体类型",RFC 4627,DOI 10.17487/RFC4627,2006 年 7 月。 |
[RFC5322] | Resnick, P.,Internet 消息格式",RFC 5322,DOI 10.17487/RFC5322,2008 年 10 月。 |
[ecma262] | ECMA 262 规范" |