| RFC 9512 | YAML 媒体类型 | 2024 年 2 月 |
| Polli 等人 | 信息性 | [页] |
本文档向 IANA 注册了 application/yaml 媒体类型和
+yaml 结构化语法后缀。两者都标识根据 YAML 规范
序列化的文档组件。¶
本文档不是互联网标准轨道规范;它是 为信息性目的而发布的。¶
本文档是互联网工程任务组 (IETF)的产物。它代表了 IETF 社群的共识。它已 接受公开审查,并已获互联网工程指导组(IESG) 批准发布。并非所有由 IESG 批准的文档 都是任何级别互联网标准的候选;参见 RFC 7841 第 2 节。¶
关于本文档当前状态、任何勘误以及 如何提供反馈的信息,可在 https://www.rfc-editor.org/info/rfc9512 获取。¶
Copyright (c) 2024 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
YAML [YAML] 是一种数据序列化 格式,能够在单个表示 流(例如文件或网络资源)中传送一个或多个文档。 它广泛用于 互联网,包括 API 领域(例如,见 [OAS]), 但相应的媒体类型和结构化语法后缀此前尚未 由 IANA 注册。¶
为提高交换 YAML 流时的互操作性,并
在交换 YAML 资源时利用内容协商机制,
本规范注册了 application/yaml 媒体类型
和 +yaml 结构化语法后缀 [MEDIATYPE]。¶
此外,它还提供了与 [YAML] 相关的安全考虑事项和互操作性 考虑事项,包括它与 [JSON] 的关系。¶
本文档中的关键词“必须”、“不得”、“要求”、“应”、“不应”、“应该”、“不应该”、“推荐”、“不推荐”、 “可以”和“可选”,当且仅当它们如这里所示 以全大写形式出现时,应按 BCP 14 [RFC2119] [RFC8174] 中的描述进行解释。¶
本文档中的术语“内容协商”和“资源” 应按 [HTTP] 中的含义解释。¶
本文档中的术语“片段”和“片段标识符” 应按 [URI] 中的含义解释。¶
本文档中的术语“表示”、“流”、“YAML 文档”、 “表示图”、“标签”、“序列化细节”、“节点”、“别名 节点”、“锚点”和“锚点名称”应按 [YAML] 中的含义解释。¶
包含 YAML 代码的图总是以 %YAML
指令开头,以提高可读性。¶
片段标识流中的一个节点。¶
以“*”开头的片段标识符 应被解释为 YAML 别名节点(见 第 1.2.1 节)。¶
对于单文档 YAML 流,空片段标识符或 以“/”开头的片段标识符应被解释为 JSON Pointer [JSON-POINTER],并在 YAML 表示图上求值,遍历别名节点;特别是, 空片段标识符引用根节点。此语法只能 引用位于由与 JSON 数据模型互操作的节点 组成的路径上的 YAML 节点(见 第 3.4 节)。¶
片段标识符并不能保证引用现有节点。 因此,应用程序应该定义如何处理未解析的别名节点。¶
本节描述如何使用 别名节点(见 [YAML] 的第 3.2.2.2 节和第 7.1 节) 作为片段标识符来指定节点。¶
YAML 别名节点可以在 URI 片段标识符中表示, 方式是使用 UTF-8 [UTF-8] 将其编码为字节,但这些字符的百分号编码不被 [URI] 第 3.5 节中的 fragment 规则允许。¶
如果多个节点匹配同一个片段标识符, 则选择第一个出现的匹配项。¶
关心片段标识符互操作性的用户:¶
在下面的示例资源中,相对引用(见 [URI] 第
4.2 节)
file.yaml#*foo 标识第一个别名节点
*foo,该节点指向值为 scalar 的节点,
而不是第二个文档中的那个节点;而相对引用
file.yaml#*document_2 标识第二个文档
{one: [a, sequence]} 的根节点。¶
%YAML 1.2 --- one: &foo scalar two: &bar - some - sequence - items ... %YAML 1.2 --- &document_2 one: &foo [a, sequence]
本节包含 IANA 注册
application/yaml 媒体类型和 +yaml 结构化语法后缀
所需的信息,依据 [MEDIATYPE]。¶
application/yaml
YAML 的媒体类型是 application/yaml;
以下信息作为此媒体类型的注册表单。¶
+yaml
结构化语法后缀
后缀
+yaml可以与任何媒体类型一起使用,只要其
表示遵循
为 application/yaml 建立的表示。
结构化语法后缀注册表单如下。
有关注册表单各部分的定义,见 [MEDIATYPE]。¶
YAML 不是标记语言(YAML)¶
+yaml¶
同 application/yaml¶
同 application/yaml¶
与 application/yaml 不同,
没有为 +yaml 定义
片段标识语法。¶
具体的 xxx/yyy+yaml 媒体类型
需要定义片段标识符的语法和语义,
因为为 application/yaml
定义的那些语法和语义不会适用,除非明确说明。¶
同 application/yaml¶
httpapi@ietf.org 或 art@ietf.org¶
见本文档的作者地址部分。¶
IETF¶
YAML 是一种演进中的语言,随着时间推移, 一些特性被添加,另一些特性被移除。¶
application/yaml 媒体类型注册独立于
YAML 版本。
这允许对版本无关的 YAML 资源进行内容协商。¶
关心与特定 YAML 版本相关特性的实现者
可以在 YAML 文档中使用 %YAML 指令
指定它(见 [YAML] 第 6.8.1 节)。¶
YAML 流可以包含零个或多个 YAML 文档。¶
当接收多文档流时, 只期望单文档流的应用程序 应发出错误信号,而不是忽略额外文档。¶
当前实现认为流中的不同文档彼此独立, 类似于 JSON 文本序列(见 [RFC7464]); 锚点等元素不保证能够跨不同文档 被引用。¶
"yaml" 文件名扩展名是首选; 它在 Web 上最流行且广泛使用。 "yml" 文件名扩展名仍在使用。 在同一上下文中同时使用两个文件名扩展名 可能导致互操作性问题 (例如,当 "config.yaml" 和 "config.yml" 同时存在时)。¶
使用流式集合样式时(见 [YAML] 第 7.4 节), YAML 文档可能看起来像 JSON [JSON]; 因此,适用类似的互操作性考虑事项。¶
当使用 YAML 作为更高效的格式 来序列化意图作为 JSON 使用的信息时, 未反映在表示图中 且被归类为表示或序列化细节的信息 (见 [YAML] 第 3.2 节)可以被丢弃。 这包括注释(见 [YAML] 第 3.2.3.3 节)、 指令,以及没有 JSON 对应物的别名节点(见 [YAML] 第 7.1 节)。¶
%YAML 1.2 --- # This comment will be lost # when serializing in JSON. Title: type: string maxLength: &text_limit 64 Name: type: string maxLength: *text_limit # Replaced by the value 64.
实现者需要确保相关 信息不会在处理期间丢失。 例如,他们可以认为 将别名节点替换为静态值是可接受的。¶
在某些情况下,实现者可能希望 定义允许的 YAML 特性列表, 同时考虑以下特性可能与 [JSON] 存在互操作性 问题:¶
.inf 和 .nan 浮点值,因为 JSON 不支持它们¶
!!timestamp 等标签关联的类型,
这些类型包含在较旧 YAML 版本的默认模式中¶
!!python/object
和 !mytag 等自定义和本地标签(见 [YAML]
第 2.4 节)¶
%YAML 1.2
---
non-json-keys:
0: a number
[0, 1]: a sequence
? {k: v}
: a map
---
non-json-keys:
!date 2020-01-01: a timestamp
non-json-value: !date 2020-01-01
...
媒体类型和媒体类型后缀的安全要求 在 [MEDIATYPE] 第 4.6 节中讨论。¶
使用 YAML 标签时应谨慎,因为它们的解析 可能触发意外代码执行。¶
反序列化器中的代码执行应默认禁用, 并且只能显式启用。 在后一种情况下,实现应确保(例如通过特定函数) 代码执行在严格限定的时间/内存限制内完成。¶
许多实现提供了能解决这些问题的安全反序列化器。¶
YAML 文档是有根、连通、有向图, 并且可以包含引用循环, 因此不能把它们当作简单树处理(见 [YAML] 第 3.2.1 节)。 将其当作简单树处理的实现 在遍历 YAML 表示图时有陷入无限循环的风险。 这可能发生在:¶
即使表示图不是循环的,将其当作 简单树处理也可能导致不当行为,例如触发 指数级数据膨胀(例如 Billion Laughs 攻击)。¶
%YAML 1.2 --- x1: &a1 ["a", "a"] x2: &a2 [*a1, *a1] x3: &a3 [*a2, *a2]
可以通过限制锚点递归深度 并在处理前验证输入的处理器来解决此问题; 即使在这些情况下,也必须 仔细测试将要使用的实现。 当以不支持引用循环的格式序列化 YAML 表示图时, 同样的考虑事项也适用(见 第 3.4 节)。¶
IANA 已使用“媒体
类型”
注册表,根据第 2.1 节中的注册信息更新
媒体类型 application/yaml。¶
IANA 已使用“结构化
语法后缀”注册表,根据
第 2.2 节中的注册信息更新结构化语法后缀
+yaml。¶
此示例展示了一组无法 基于 JSON 数据模型引用的 YAML 节点,因为它们的映射键 不是字符串。¶
%YAML 1.2
---
a-map-cannot:
? {be: expressed}
: with a JSON Pointer
0: no numeric mapping keys in JSON
在此示例中,片段 #/0 并不引用现有
节点。¶
%YAML 1.2 --- 0: "JSON Pointer `#/0` references a string mapping key."
在此 YAML 文档中,#/foo/bar/baz 片段标识符
遍历表示图并引用字符串 you。
此外,循环引用的存在意味着
存在无限多个片段标识符 #/foo/bat/../bat/bar
引用 &anchor 节点。¶
%YAML 1.2 --- anchor: &anchor baz: you foo: &foo bar: *anchor bat: *foo
许多 YAML 实现会在表示图中解析
YAML 1.1 中定义的合并键“<<:”。
这意味着片段 #/book/author/given_name 引用字符串
Federico,
并且片段 #/book/<< 将不引用任何现有节点。¶
%YAML 1.1
---
# Many implementations use merge keys.
the-viceroys: &the-viceroys
title: The Viceroys
author:
given_name: Federico
family_name: De Roberto
book:
<<: *the-viceroys
title: The Illusion