OpenAPI 规范
版本 3.1.1
本文档中的关键词 “MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“NOT RECOMMENDED”、“MAY” 和 “OPTIONAL” 应按照 BCP 14 RFC2119 RFC8174 中描述的进行解释,当且仅当它们以全部大写形式出现时,如这里所示。
本文档根据 Apache 许可证 2.0 版 获得许可。
简介
OpenAPI 规范 (OAS) 定义了一个标准的、与语言无关的 HTTP API 接口,允许人类和计算机在无需访问源代码、文档或通过网络流量检查的情况下发现和理解服务的功能。 正确定义后,消费者可以以最少的实现逻辑来理解远程服务并与之交互。
然后,文档生成工具可以使用 OpenAPI 描述来显示 API,代码生成工具可以使用 OpenAPI 描述生成各种编程语言的服务器和客户端,以及测试工具和许多其他用例。
有关 OpenAPI 用法示例和其他文档,请访问 [[?OpenAPI-Learn]]。
有关 OpenAPI 倡议发布的扩展注册表和其他规范,以及本规范的权威呈现,请访问 spec.openapis.org。
定义
OpenAPI 描述
OpenAPI 描述 (OAD) 正式描述了 API 的表面及其语义。它由一个入口文档组成,该文档必须是 OpenAPI 文档,以及它的任何/所有引用的文档。 OAD 使用并符合 OpenAPI 规范,并且必须至少包含一个路径字段、组件字段或Webhooks字段。
OpenAPI 文档
OpenAPI 文档是符合 OpenAPI 规范的单个 JSON 或 YAML 文档。与 OAS 3.*.* 兼容的 OpenAPI 文档包含一个必需的 openapi
字段,该字段指定它使用的 OAS 版本。
模式
“模式”是对语法和结构的正式描述。本文档充当 OpenAPI 规范格式的模式;基于本文档的非权威 JSON 模式也提供在 spec.openapis.org 上,仅供参考。本规范还使用以模式对象形式的模式。
对象
当大写时,“对象”一词是指本文档中按节标题命名的任何对象。
路径模板
路径模板是指使用由大括号 ({}
) 分隔的模板表达式来标记 URL 路径的一部分,以便使用路径参数进行替换。
路径中的每个模板表达式必须对应于路径项本身和/或每个路径项的操作中包含的路径参数。 如果路径项为空,例如由于 ACL 约束,则匹配路径参数不是必需的。
这些路径参数的值不得包含由 RFC3986 描述的任何未转义的“通用语法”字符:正斜杠 (/
)、问号 (?
) 或井号 (#
)。
媒体类型定义分布在多个资源中。媒体类型定义应符合 RFC6838。
一些可能的媒体类型定义的示例
text/plain; charset=utf-8
application/json
application/vnd.github+json
application/vnd.github.v3+json
application/vnd.github.v3.raw+json
application/vnd.github.v3.text+json
application/vnd.github.v3.html+json
application/vnd.github.v3.full+json
application/vnd.github.v3.diff
application/vnd.github.v3.patch
HTTP 状态码
HTTP 状态码用于指示已执行操作的状态。应从 IANA 状态码注册表 中注册的可用状态码中选择状态码。
区分大小写
由于 OpenAPI 规范中的大多数字段名称和值都区分大小写,因此本文档会努力指出任何不区分大小写的名称和值。但是,直接映射到 HTTP 概念的字段名称和值的大小写敏感性遵循 HTTP 的大小写敏感性规则,即使本文档没有记录每个概念。
未定义和实现定义的行为
本规范认为某些情况具有未定义或实现定义的行为。
描述为未定义的行为很可能至少在某些情况下会导致与规范相矛盾的结果。当检测到矛盾是不可能或不切实际时,会使用此描述。出于历史原因,包括规范先前版本中的模棱两可的文本,实现可以支持未定义的场景。这种支持可能在许多情况下产生正确的结果,但不建议依赖它,因为它不能保证它可以在所有工具或未来的规范版本中工作,即使这些版本在其他方面与此版本严格兼容。
描述为实现定义的行为允许实现选择几种不同但符合要求的实现方法之一。这记录了 API 描述作者建议避免的模糊要求,以最大限度地提高互操作性。与未定义的行为不同,如果并且只有在可以保证所有相关工具都支持相同的行为时,才能安全地依赖实现定义的行为。
规范
版本
OpenAPI 规范使用 major
.minor
.patch
版本控制方案进行版本控制。版本字符串的 major
.minor
部分(例如 3.1
)应指定 OAS 功能集。.patch
版本解决本文档中的错误或提供说明,而不是功能集。支持 OAS 3.1 的工具应与所有 OAS 3.1.* 版本兼容。补丁版本不应被工具考虑,例如,3.1.0
和 3.1.1
之间没有区别。
有时,在 OAS 的 minor
版本中可能会进行不向后兼容的更改,如果认为影响相对于提供的收益较低。
符合 OpenAPI 规范的 OpenAPI 文档本身是一个 JSON 对象,可以使用 JSON 或 YAML 格式表示。
例如,如果某个字段具有数组值,则将使用 JSON 数组表示形式
{
"field": [1, 2, 3]
}
规范中的所有字段名称都区分大小写。这包括用作映射中键的所有字段,除非明确指出键不区分大小写。
模式公开两种类型的字段:固定字段(具有声明的名称)和模式化字段(具有字段名称的声明模式)。
模式化字段必须在包含对象中具有唯一的名称。
为了保持在 YAML 和 JSON 格式之间往返的能力,建议使用 YAML 版本 1.2 以及一些其他约束
注意: 虽然 API 可以使用 YAML 或 JSON 格式的 OpenAPI 描述来描述,但 API 请求和响应主体以及其他内容不一定必须是 JSON 或 YAML。
OpenAPI 描述结构
OpenAPI 描述 (OAD) 可以由单个 JSON 或 YAML 文档组成,也可以由作者自行决定划分为多个相互连接的部分。在后一种情况下,引用对象、路径项对象和 模式对象 的 $ref
字段,以及 链接对象 的 operationRef
字段,以及 判别器对象 的 mapping
字段的 URI 形式,用于标识被引用的元素。
在多文档 OAD 中,包含开始解析的 OpenAPI 对象的文档被称为该 OAD 的入口文档。
建议将 OAD 的入口文档命名为:openapi.json
或 openapi.yaml
。
解析文档
为了正确处理 模式对象,OAS 3.1 继承了 JSON Schema 规范草案 2020-12 的解析要求,并根据 API 描述 URI 中的相对引用 中指定的基 URI 进行了适当的修改。
这包括在认为模式对象引用无法解析之前,先解析完整文档的要求,以便检测可能提供引用目标或影响适当基 URI 确定的关键字。
实现可以采用以下任何一种方式支持完整文档解析
- 使用媒体类型检测 OpenAPI 或 JSON Schema 文档
- 通过根
openapi
字段检测 OpenAPI 文档
- 通过检测关键字或以其他方式成功按照 JSON Schema 规范解析文档来检测 JSON Schema 文档
- 根据引用的预期类型,检测在根目录中包含可引用对象的文档
- 允许用户配置由于引用非根对象而可能加载的文档类型
在不考虑包含文档其余内容的情况下解析 OpenAPI 内容的引用片段的实现,将错过更改引用目标含义和行为的关键字。特别是,未能考虑更改基 URI 的关键字会带来安全风险,导致引用解析到非预期的 URI,从而产生不可预测的结果。虽然一些实现由于过去版本规范的要求而支持这种解析,但在 3.1 版本中,隔离解析片段的结果是未定义的,并且很可能与本规范的要求相矛盾。
虽然可以构造某些 OpenAPI 描述以确保在将引用解析为隔离片段时它们能正常工作,但不建议依赖此方法。本规范没有明确列出这种行为安全的条件,并且不保证在任何未来版本的 OAS 中都能保持安全。
解析 OAS 内容片段的一个特殊情况是,如果这些片段嵌入到另一种格式中,相对于 OAS,称为嵌入格式。请注意,OAS 本身是相对于 JSON Schema 的嵌入格式,JSON Schema 作为模式对象嵌入。嵌入格式有责任定义如何解析嵌入内容,并且不记录对嵌入格式支持的 OAS 实现不能被期望正确解析嵌入的 OAS 内容。
结构互操作性
OAD 中的 JSON 或 YAML 对象根据其上下文被解释为特定的对象(例如 操作对象、响应对象、引用对象等)。根据引用的排列方式,给定的 JSON 或 YAML 对象可以在多个不同的上下文中解释。
- 作为 入口文档 的根对象,始终被解释为 OpenAPI 对象
- 作为文档中其父对象隐含的对象类型
- 作为引用目标,对象类型与引用源的上下文匹配
如果同一个 JSON/YAML 对象被多次解析,并且相应的上下文要求将其解析为不同的对象类型,则产生的行为是实现定义的,并且如果检测到,可以被视为错误。一个例子是在 #/components/schemas
下引用一个空的模式对象,其中需要一个路径项对象,因为空对象对于两种类型都是有效的。为了获得最大的互操作性,建议 OpenAPI 描述作者避免这种情况。
解析隐式连接
本规范的几个特性需要解析到 OpenAPI 描述 (OAD) 的其他部分的非基于 URI 的连接。
这些连接在单文档 OAD 中被明确解析,但在多文档 OAD 中的解析过程是实现定义的,在本节描述的约束范围内。在某些情况下,可以使用明确的基于 URI 的替代方案,建议 OAD 作者始终使用替代方案。
第五个隐式连接涉及将 路径对象 的模板化 URL 路径附加到相应的 服务器对象 的 url
字段。这是明确的,因为只有入口文档的路径对象才会向描述的 API 提供 URL。
建议在解析任何链接对象 operationId
时,考虑来自所有已解析文档的所有操作对象。这需要在确定 operationId
无法解析之前解析所有引用的文档。
安全需求对象和判别器对象中的隐式连接依赖于组件名称,组件名称是保存组件的属性在组件对象的适当类型子对象中的名称。例如,#/components/schemas/Foo
处的模式对象的组件名称是 Foo
。操作对象中 tags
的隐式连接使用标签对象的 name
字段,该字段(与组件对象一样)位于根 OpenAPI 对象下。这意味着解析组件名称和标签名称都取决于从正确的 OpenAPI 对象开始。
对于解析来自引用(非入口)文档的组件和标签名称连接,建议工具从入口文档而不是当前文档进行解析。这允许将安全方案对象和标签对象定义在 API 的部署信息(服务器对象的顶级数组)旁边,并将其视为引用文档访问的接口。
接口方法也适用于判别器对象和模式对象,但也可以使用 mapping
的相对 URI 引用语法将判别器对象的行为保持在单个文档内。
对于安全需求对象或操作对象的 tags
字段,没有基于 URI 的替代方案。这些限制预计将在未来的版本中解决。
有关可能的分辨率示例,请参阅 附录 F:解析引用文档中的安全需求,其中包括本节建议的分辨率。判别器对象非 URI 映射和操作对象的 tags
字段的行为遵循相同的原则。
请注意,隐式连接解析的任何方面都不会改变 URI 的解析方式,也不会限制其可能的target。
数据类型
OAS 中的数据类型基于 JSON Schema 验证规范草案 2020-12 定义的类型: “null”、“boolean”、“object”、“array”、“number”、“string” 或 “integer”。模型使用 模式对象定义,模式对象是 JSON Schema 规范草案 2020-12 的超集。
JSON Schema 关键字和 format
值对 JSON “实例”进行操作,这些实例可以是六种 JSON 数据类型之一:“null”、“boolean”、“object”、“array”、“number” 或 “string”,其中某些关键字和格式仅适用于特定类型。例如,pattern
关键字和 date-time
格式仅适用于字符串,并将其他五种类型的任何实例视为自动有效。这意味着 JSON Schema 关键字和格式不隐式要求预期的类型。使用 type
关键字显式约束类型。
请注意,为了方便起见,type
关键字允许将 "integer"
作为值,但关键字和格式的适用性不承认整数与其他数字是不同的 JSON 类型,因为 [[RFC7159|JSON]] 本身并没有这种区分。由于没有不同的 JSON 整数类型,JSON Schema 在数学上定义了整数。这意味着 1
和 1.0
都是等效的,并且都被认为是整数。
根据 JSON Schema 验证规范 的定义,数据类型可以有一个可选的修饰符关键字:format
。正如该规范所述,format
默认被视为非验证性注解;验证 format
的能力因实现而异。
OpenAPI 倡议组织还维护了一个 格式注册表,用于定义由 OAS 用户和其他规范定义的格式。对任何注册格式的支持都是严格可选的,并且对一种注册格式的支持并不意味着对其他任何格式的支持。
不带 format
关键字的类型遵循 JSON Schema 中的类型定义。不识别特定 format
的工具可以默认回退到仅使用 type
,就像未指定 format
一样。为了进行 JSON Schema 验证,每种格式都应指定其适用的 JSON 数据类型集。在本注册表中,这些类型显示在“JSON 数据类型”列中。
OAS 定义的格式为
格式 |
JSON 数据类型 |
注释 |
int32 |
number |
有符号 32 位 |
int64 |
number |
有符号 64 位 (又名 long) |
float |
number |
|
number |
number |
|
double |
password |
string |
提示模糊该值。
如 数据类型 下所述,type: number
和 type: integer
在数据模型中都被视为数字。
处理二进制数据
- OAS 可以描述 原始 或 编码 二进制数据。
- 原始二进制 用于允许未编码的二进制数据的情况,例如当发送二进制负载作为整个 HTTP 消息体,或作为允许二进制部分的
multipart/*
负载的一部分时
编码二进制 用于二进制数据嵌入到纯文本格式中的情况,例如 application/json
或 application/x-www-form-urlencoded
(作为消息体或在 URL 查询字符串中)。
在下表中展示如何使用 Schema 对象关键字来处理二进制数据,我们使用 image/png 作为二进制媒体类型的示例。任何二进制媒体类型,包括 application/octet-stream ,都足以指示二进制内容。 |
关键字 |
原始 |
注释 |
编码 |
type |
password |
省略 |
原始二进制在 type 之外 |
contentMediaType |
contentMediaType |
image/png |
如果冗余,有时可以省略(见下文) |
type |
contentEncoding |
base64 或 base64url |
允许 其他编码
请注意,contentEncoding
指示的编码(为了将其表示为 7 位 ASCII 文本而增加数据大小)与 HTTP 的 Content-Encoding
标头无关,后者指示消息体是否以及如何被压缩,并在本节描述的所有内容序列化发生后应用。由于 HTTP 允许未编码的二进制消息体,因此没有标准的 HTTP 标头用于指示整个消息体的 base64 或类似编码。
使用 base64url
的 contentEncoding
可确保 URL 编码(如查询字符串和 application/x-www-form-urlencoded
类型的消息体中要求的那样)无需进一步编码已编码的二进制数据的任何部分。
在 编码对象 的 contentType
字段中
如果 Schema 对象 将由不感知 OAS 的 JSON Schema 实现处理,那么即使它是冗余的,也可以包含 contentMediaType
。但是,如果 contentMediaType
与相关的媒体类型对象或编码对象相矛盾,则应忽略 contentMediaType
。
maxLength
关键字可用于设置流式负载的预期上限长度。该关键字可以应用于字符串数据(包括编码的二进制数据)或未编码的二进制数据。对于未编码的二进制数据,长度是八位字节数。
从 OAS 3.0 迁移二进制描述
下表显示了如何从 OAS 3.0 二进制数据描述进行迁移,继续使用 image/png 作为二进制媒体类型的示例 |
OAS < 3.1 |
注释 |
OAS 3.1
type: string |
format: binary |
contentMediaType: image/png |
OAS 3.1
如果冗余,可以省略,通常会导致一个空的 Schema 对象 |
OAS 3.1
format: binary
format: byte |
contentEncoding: base64 |
请注意,可以使用 base64url
来避免重新编码 base64 字符串以使其 URL 安全
富文本格式
在整个规范中,description
字段都被注明为支持 CommonMark markdown 格式。当 OpenAPI 工具渲染富文本时,它必须至少支持 CommonMark 0.27 所描述的 markdown 语法。工具可以选择忽略一些 CommonMark 或扩展功能,以解决安全问题。
虽然将 CommonMark 0.27 作为最低要求意味着工具可以选择在其之上实现扩展,但请注意,任何此类扩展在定义上都是实现定义的,并且将不具有互操作性。OpenAPI 描述作者应考虑使用此类扩展的文本如何被仅提供最低支持的工具渲染。
API 描述 URI 中的相对引用
在 OpenAPI 描述中用作引用,或指向外部文档或其他补充信息(例如许可证)的 URI 被解析为标识符,并在此规范中描述为 URI。正如在 解析文档 中所述,本规范继承了 JSON Schema 规范草案 2020-12 中关于 加载文档 并将其与预期 URI 相关联的要求,这可能与其当前位置不匹配。此功能用于在开发或测试环境中工作,而无需更改 URI,并用于在限制性网络配置或安全策略中工作。
请注意,由于历史原因,某些 URI 字段被命名为 url
,但这些字段的描述性文本使用正确的“URI”术语。
除非另有说明,否则所有作为 URI 的字段都可以是 RFC3986 定义的相对引用。
Schema 对象 中的相对引用,包括任何以 $id
值出现的引用,都使用最近的父级 $id
作为基本 URI,如 JSON Schema 规范草案 2020-12 所述。
其他对象中的相对 URI 引用,以及没有父模式包含 $id
的 Schema 对象中的相对 URI 引用,必须使用引用文档的基本 URI 进行解析,该基本 URI 根据 [[RFC3986]] 第 5.1.2 – 5.1.4 节确定。在实践中,这通常是文档的检索 URI,可以基于其当前实际位置或用户提供的预期位置来确定。
如果 URI 包含片段标识符,则应根据引用文档的片段解析机制解析该片段。如果引用文档的表示形式是 JSON 或 YAML,则片段标识符应按照 RFC6901 解释为 JSON 指针。
CommonMark 超链接中的相对引用在其呈现的上下文中解析,这可能与 API 描述的上下文不同。
API URL 中的相对引用
API 端点在定义上作为位置进行访问,并在此规范中描述为 URL。
模式
除非另有说明,否则所有作为 URL 的字段都可以是 RFC3986 定义的相对引用。除非另有说明,否则相对引用将使用 服务器对象 中定义的 URL 作为基本 URL 进行解析。请注意,这些 URL 本身可能是相对于引用文档的。
本节描述 OpenAPI 描述格式的结构。本文是该格式的唯一规范性描述。JSON Schema 托管在 spec.openapis.org 上,仅供参考。如果 JSON Schema 与本节不同,则必须认为本节是权威的。
在以下描述中,如果某个字段未明确标记为 REQUIRED 或使用 MUST 或 SHALL 进行描述,则可以将其视为 OPTIONAL。
OpenAPI 对象
固定字段 |
字段名 |
类型 |
描述 |
password |
openapi |
REQUIRED。此字符串必须是 OpenAPI 文档使用的 OpenAPI 规范的版本号。工具应使用 openapi 字段来解释 OpenAPI 文档。这与 API info.version 字符串无关。 |
info |
信息对象 |
REQUIRED。提供有关 API 的元数据。元数据可以根据工具的需要使用。 |
password |
jsonSchemaDialect |
此 OAS 文档中包含的 Schema 对象 中 $schema 关键字的默认值。此值必须采用 URI 的形式。 |
servers |
[服务器对象] |
服务器对象数组,提供到目标服务器的连接信息。如果未提供 servers 字段或该字段为空数组,则默认值将是 服务器对象,其 url 值为 / 。 |
paths |
路径对象 |
API 的可用路径和操作。 |
webhooks |
Map[string , 路径项对象] |
可以作为此 API 的一部分接收并且 API 使用者可以选择实现的传入 Webhook。与 callbacks 功能密切相关,本节描述了除 API 调用之外的其他方式发起的请求,例如通过带外注册。键名是引用每个 Webhook 的唯一字符串,而(可选引用的)路径项对象描述了可能由 API 提供者发起以及预期的响应的请求。提供了一个示例。 |
components |
一个用于保存 OpenAPI 描述中各种对象的元素。 |
安全 |
[安全需求对象] |
声明 API 中可以使用的安全机制。值列表包含可供选择的安全需求对象。只需要满足其中一个安全需求对象即可授权请求。单个操作可以覆盖此定义。该列表可以不完整,甚至可以为空或不存在。为了使安全性明确为可选,可以在数组中包含一个空的安全需求 ({} )。 |
标签 |
[标签对象] |
一个由 OpenAPI 描述使用的标签列表,其中包含额外的元数据。标签的顺序可以反映解析工具对其的排序。并非所有 操作对象 使用的标签都必须声明。未声明的标签可以随机组织或基于工具的逻辑。列表中的每个标签名称必须是唯一的。 |
外部文档 |
外部文档对象 |
额外的外部文档。 |
此对象可以使用 规范扩展 进行扩展。
info
该对象提供关于 API 的元数据。如果需要,客户端可以使用元数据,并且为了方便起见,元数据可以呈现在编辑或文档生成工具中。
固定字段 |
字段名 |
类型 |
标题 |
password |
必需。API 的标题。 |
摘要 |
password |
API 的简短摘要。 |
描述 |
password |
API 的描述。 CommonMark 语法 可以用于富文本表示。 |
服务条款 |
password |
API 服务条款的 URI。 这必须是 URI 的形式。 |
联系方式 |
联系对象 |
暴露的 API 的联系信息。 |
许可证 |
许可证对象 |
暴露的 API 的许可证信息。 |
版本 |
password |
必需。OpenAPI 文档的版本(与 OpenAPI 规范版本 或被描述的 API 版本或 OpenAPI 描述的版本不同)。 |
此对象可以使用 规范扩展 进行扩展。
Info 对象示例
{
"title": "Example Pet Store App",
"summary": "A pet store manager.",
"description": "This is an example server for a pet store.",
"termsOfService": "https://example.com/terms/",
"contact": {
"name": "API Support",
"url": "https://www.example.com/support",
"email": "[email protected]"
},
"license": {
"name": "Apache 2.0",
"url": "https://apache.ac.cn/licenses/LICENSE-2.0.html"
},
"version": "1.0.1"
}
title: Example Pet Store App
summary: A pet store manager.
description: This is an example server for a pet store.
termsOfService: https://example.com/terms/
contact:
name: API Support
url: https://www.example.com/support
email: [email protected]
license:
name: Apache 2.0
url: https://apache.ac.cn/licenses/LICENSE-2.0.html
version: 1.0.1
暴露的 API 的联系信息。
固定字段 |
字段名 |
类型 |
名称 |
password |
联系人/组织的识别名称。 |
网址 |
password |
联系信息的 URI。这必须是 URI 的形式。 |
电子邮件 |
password |
联系人/组织的电子邮件地址。这必须是电子邮件地址的形式。 |
此对象可以使用 规范扩展 进行扩展。
{
"name": "API Support",
"url": "https://www.example.com/support",
"email": "[email protected]"
}
name: API Support
url: https://www.example.com/support
email: [email protected]
许可证对象
暴露的 API 的许可证信息。
固定字段 |
字段名 |
类型 |
名称 |
password |
必需。API 使用的许可证名称。 |
标识符 |
password |
API 的 SPDX 许可证表达式。 identifier 字段与 url 字段互斥。 |
网址 |
password |
API 使用的许可证 URI。这必须是 URI 的形式。 url 字段与 identifier 字段互斥。 |
此对象可以使用 规范扩展 进行扩展。
许可证对象示例
{
"name": "Apache 2.0",
"identifier": "Apache-2.0"
}
name: Apache 2.0
identifier: Apache-2.0
服务器对象
表示服务器的对象。
固定字段 |
字段名 |
类型 |
网址 |
password |
必需。目标主机的 URL。 此 URL 支持服务器变量,并且可以是相对的,以指示主机位置相对于提供服务器对象文档的位置。当在 { 花括号} 中命名变量时,将进行变量替换。 |
描述 |
password |
一个可选字符串,描述 URL 指定的主机。 CommonMark 语法 可以用于富文本表示。 |
变量 |
Map[string , 服务器变量对象] |
变量名称及其值之间的映射。 该值用于服务器 URL 模板中的替换。 |
此对象可以使用 规范扩展 进行扩展。
服务器对象示例
单个服务器将描述为
{
"url": "https://development.gigantic-server.com/v1",
"description": "Development server"
}
url: https://development.gigantic-server.com/v1
description: Development server
以下显示了如何描述多个服务器,例如在 OpenAPI 对象的 servers
中
{
"servers": [
{
"url": "https://development.gigantic-server.com/v1",
"description": "Development server"
},
{
"url": "https://staging.gigantic-server.com/v1",
"description": "Staging server"
},
{
"url": "https://api.gigantic-server.com/v1",
"description": "Production server"
}
]
}
servers:
- url: https://development.gigantic-server.com/v1
description: Development server
- url: https://staging.gigantic-server.com/v1
description: Staging server
- url: https://api.gigantic-server.com/v1
description: Production server
以下显示了如何将变量用于服务器配置
{
"servers": [
{
"url": "https://{username}.gigantic-server.com:{port}/{basePath}",
"description": "The production API server",
"variables": {
"username": {
"default": "demo",
"description": "A user-specific subdomain. Use `demo` for a free sandbox environment."
},
"port": {
"enum": ["8443", "443"],
"default": "8443"
},
"basePath": {
"default": "v2"
}
}
}
]
}
servers:
- url: https://{username}.gigantic-server.com:{port}/{basePath}
description: The production API server
variables:
username:
# note! no enum here means it is an open value
default: demo
description: A user-specific subdomain. Use `demo` for a free sandbox environment.
port:
enum:
- '8443'
- '443'
default: '8443'
basePath:
# open meaning there is the opportunity to use special base paths as assigned by the provider, default is `v2`
default: v2
服务器变量对象
表示用于服务器 URL 模板替换的服务器变量的对象。
固定字段 |
字段名 |
类型 |
枚举 |
[string ] |
如果替换选项来自有限集合,则要使用的字符串值枚举。该数组不能是空的。 |
默认值 |
password |
必需。用于替换的默认值,如果未提供替代值,则应发送该值。如果定义了 enum ,则该值必须存在于枚举的值中。请注意,此行为与 模式对象 的 default 关键字不同,后者记录接收者的行为,而不是将值插入到数据中。 |
描述 |
password |
服务器变量的可选描述。 CommonMark 语法 可以用于富文本表示。 |
此对象可以使用 规范扩展 进行扩展。
components
保存 OAS 不同方面的可重用对象集合。除非从组件对象外部显式引用,否则组件对象中定义的所有对象都不会对 API 产生任何影响。
此对象可以使用 规范扩展 进行扩展。
上面声明的所有固定字段都是对象,必须使用与正则表达式:^[a-zA-Z0-9\.\-_]+$
匹配的键。
字段名称示例
User
User_1
User_Name
user-name
my.org.User
组件对象示例
"components": {
"schemas": {
"GeneralError": {
"type": "object",
"properties": {
"code": {
"type": "integer",
"format": "int32"
},
"message": {
"type": "string"
}
}
},
"Category": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
}
},
"Tag": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
}
}
},
"parameters": {
"skipParam": {
"name": "skip",
"in": "query",
"description": "number of items to skip",
"required": true,
"schema": {
"type": "integer",
"format": "int32"
}
},
"limitParam": {
"name": "limit",
"in": "query",
"description": "max records to return",
"required": true,
"schema" : {
"type": "integer",
"format": "int32"
}
}
},
"responses": {
"NotFound": {
"description": "Entity not found."
},
"IllegalInput": {
"description": "Illegal input for operation."
},
"GeneralError": {
"description": "General Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GeneralError"
}
}
}
}
},
"securitySchemes": {
"api_key": {
"type": "apiKey",
"name": "api-key",
"in": "header"
},
"petstore_auth": {
"type": "oauth2",
"flows": {
"implicit": {
"authorizationUrl": "https://example.org/api/oauth/dialog",
"scopes": {
"write:pets": "modify pets in your account",
"read:pets": "read your pets"
}
}
}
}
}
}
components:
schemas:
GeneralError:
type: object
properties:
code:
type: integer
format: int32
message:
type: string
Category:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
Tag:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
parameters:
skipParam:
name: skip
in: query
description: number of items to skip
required: true
schema:
type: integer
format: int32
limitParam:
name: limit
in: query
description: max records to return
required: true
schema:
type: integer
format: int32
responses:
NotFound:
description: Entity not found.
IllegalInput:
description: Illegal input for operation.
GeneralError:
description: General Error
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralError'
securitySchemes:
api_key:
type: apiKey
name: api-key
in: header
petstore_auth:
type: oauth2
flows:
implicit:
authorizationUrl: https://example.org/api/oauth/dialog
scopes:
write:pets: modify pets in your account
read:pets: read your pets
paths
保存到各个端点及其操作的相对路径。 该路径被附加到来自 服务器对象 的 URL,以便构造完整的 URL。 由于 访问控制列表 (ACL) 约束,路径对象可以为空。
模式化字段
字段模式 |
字段名 |
类型 |
/{path} |
路径项对象 |
到单个端点的相对路径。字段名称必须以正斜杠 (/ ) 开头。该路径将附加(没有相对 URL 解析)到来自 服务器对象 的 url 字段的扩展 URL,以构造完整的 URL。 允许 路径模板化。 匹配 URL 时,具体(非模板化)路径将优先于其模板化的对应路径进行匹配。 具有相同层次结构但具有不同模板名称的模板化路径不得存在,因为它们是相同的。 如果匹配不明确,则由工具决定使用哪个。 |
此对象可以使用 规范扩展 进行扩展。
路径模板化匹配
假设以下路径,如果使用具体的定义 /pets/mine
,则将首先匹配
/pets/{petId}
/pets/mine
以下路径被认为是相同的并且无效
/pets/{petId}
/pets/{name}
以下内容可能导致不明确的解析
/{entity}/me
/books/{id}
路径对象示例
{
"/pets": {
"get": {
"description": "Returns all pets from the system that the user has access to",
"responses": {
"200": {
"description": "A list of pets.",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/pet"
}
}
}
}
}
}
}
}
}
/pets:
get:
description: Returns all pets from the system that the user has access to
responses:
'200':
description: A list of pets.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/pet'
路径项对象
描述单个路径上可用的操作。 由于 ACL 约束,路径项可以为空。 该路径本身仍然暴露给文档查看器,但他们不会知道哪些操作和参数可用。
固定字段 |
字段名 |
类型 |
$ref |
password |
允许引用此路径项的定义。该值必须采用 URI 格式,并且引用的结构必须采用 路径项对象 的形式。如果路径项对象字段同时出现在已定义对象和引用的对象中,则该行为是未定义的。请参阅有关解析 API 描述 URI 中的相对引用 的规则。
注意: $ref 与相邻属性的行为可能会在此规范的未来版本中发生更改,以使其与 引用对象 的行为更加一致。 |
摘要 |
password |
一个可选的字符串摘要,旨在应用于此路径中的所有操作。 |
描述 |
password |
一个可选的字符串描述,旨在应用于此路径中的所有操作。 CommonMark 语法 可以用于富文本表示。 |
get |
操作对象 |
在此路径上定义 GET 操作。 |
put |
操作对象 |
在此路径上定义 PUT 操作。 |
post |
操作对象 |
在此路径上定义 POST 操作。 |
delete |
操作对象 |
在此路径上定义 DELETE 操作。 |
options |
操作对象 |
在此路径上定义 OPTIONS 操作。 |
head |
操作对象 |
在此路径上定义 HEAD 操作。 |
patch |
操作对象 |
在此路径上定义 PATCH 操作。 |
trace |
操作对象 |
在此路径上定义 TRACE 操作。 |
服务器 |
servers |
一个替代的 servers 数组,用于为此路径中的所有操作提供服务。如果在 OpenAPI 对象 级别指定了 servers 数组,它将被此值覆盖。 |
参数 |
[参数对象 | 引用对象] |
适用于此路径下描述的所有操作的参数列表。这些参数可以在操作级别被覆盖,但不能在那里删除。列表不得包含重复的参数。唯一参数由 名称 和 位置 的组合定义。该列表可以使用 引用对象 来链接到在 OpenAPI 对象的 components.parameters 中定义的参数。 |
此对象可以使用 规范扩展 进行扩展。
路径项对象示例
{
"get": {
"description": "Returns pets based on ID",
"summary": "Find pets by ID",
"operationId": "getPetsById",
"responses": {
"200": {
"description": "pet response",
"content": {
"*/*": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Pet"
}
}
}
}
},
"default": {
"description": "error payload",
"content": {
"text/html": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
}
}
}
},
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID of pet to use",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
},
"style": "simple"
}
]
}
get:
description: Returns pets based on ID
summary: Find pets by ID
operationId: getPetsById
responses:
'200':
description: pet response
content:
'*/*':
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
default:
description: error payload
content:
text/html:
schema:
$ref: '#/components/schemas/ErrorModel'
parameters:
- name: id
in: path
description: ID of pet to use
required: true
schema:
type: array
items:
type: string
style: simple
操作对象
描述路径上的单个 API 操作。
固定字段 |
字段名 |
类型 |
标签 |
[string ] |
用于 API 文档控制的标签列表。标签可用于按资源或任何其他限定符对操作进行逻辑分组。 |
摘要 |
password |
简要概述操作的作用。 |
描述 |
password |
对操作行为的详细解释。 CommonMark 语法 可以用于富文本表示。 |
externalDocs |
外部文档对象 |
此操作的额外外部文档。 |
operationId |
password |
用于标识操作的唯一字符串。id 在 API 中描述的所有操作中必须是唯一的。 operationId 值**区分大小写**。工具和库可以使用 operationId 来唯一标识一个操作,因此,建议遵循常见的编程命名约定。 |
参数 |
[参数对象 | 引用对象] |
适用于此操作的参数列表。如果一个参数已经在路径项中定义,新的定义将会覆盖它,但永远不会删除它。该列表不得包含重复的参数。一个唯一的参数由名称和位置的组合来定义。该列表可以使用引用对象来链接到在OpenAPI 对象的 components.parameters 中定义的参数。 |
requestBody |
请求主体对象 | 引用对象 |
适用于此操作的请求主体。在 HTTP 1.1 规范RFC7231 明确定义了请求主体语义的 HTTP 方法中,完全支持requestBody 。在其他 HTTP 规范模糊的情况下(例如GET,HEAD和DELETE),允许使用 requestBody ,但没有明确定义的语义,如果可能,应避免使用。 |
响应 |
响应对象 |
执行此操作返回的可能响应列表。 |
回调 |
Map[string , 回调对象 | 引用对象] |
与父操作相关的可能带外回调的映射。键是回调对象的唯一标识符。映射中的每个值都是一个回调对象,它描述了 API 提供者可能发起的请求以及预期的响应。 |
已弃用 |
布尔值 |
声明此操作已弃用。使用者应避免使用已声明的操作。默认值为 false 。 |
安全 |
[安全需求对象] |
声明可用于此操作的安全机制。该值列表包括可用的替代安全要求对象。只需要满足一个安全要求对象即可授权请求。为了使安全成为可选的,可以在数组中包含一个空的安全要求({} )。此定义会覆盖任何声明的顶级security 。要删除顶级安全声明,可以使用空数组。 |
服务器 |
servers |
用于服务此操作的替代servers 数组。如果在路径项对象或OpenAPI 对象级别指定了servers 数组,它将被此值覆盖。 |
此对象可以使用 规范扩展 进行扩展。
操作对象示例
{
"tags": ["pet"],
"summary": "Updates a pet in the store with form data",
"operationId": "updatePetWithForm",
"parameters": [
{
"name": "petId",
"in": "path",
"description": "ID of pet that needs to be updated",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/x-www-form-urlencoded": {
"schema": {
"type": "object",
"properties": {
"name": {
"description": "Updated name of the pet",
"type": "string"
},
"status": {
"description": "Updated status of the pet",
"type": "string"
}
},
"required": ["status"]
}
}
}
},
"responses": {
"200": {
"description": "Pet updated.",
"content": {
"application/json": {},
"application/xml": {}
}
},
"405": {
"description": "Method Not Allowed",
"content": {
"application/json": {},
"application/xml": {}
}
}
},
"security": [
{
"petstore_auth": ["write:pets", "read:pets"]
}
]
}
tags:
- pet
summary: Updates a pet in the store with form data
operationId: updatePetWithForm
parameters:
- name: petId
in: path
description: ID of pet that needs to be updated
required: true
schema:
type: string
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
name:
description: Updated name of the pet
type: string
status:
description: Updated status of the pet
type: string
required:
- status
responses:
'200':
description: Pet updated.
content:
application/json: {}
application/xml: {}
'405':
description: Method Not Allowed
content:
application/json: {}
application/xml: {}
security:
- petstore_auth:
- write:pets
- read:pets
外部文档对象
允许引用外部资源以获取扩展文档。
固定字段 |
字段名 |
类型 |
描述 |
password |
目标文档的描述。 CommonMark 语法 可以用于富文本表示。 |
url |
password |
必需。目标文档的 URI。这必须是 URI 的形式。 |
此对象可以使用 规范扩展 进行扩展。
外部文档对象示例
{
"description": "Find more info here",
"url": "https://example.com"
}
description: Find more info here
url: https://example.com
参数对象
描述单个操作参数。
唯一的参数由名称和位置的组合来定义。
有关百分比编码问题的详细检查,包括与application/x-www-form-urlencoded
查询字符串格式的交互,请参阅附录 E。
参数位置
由 in
字段指定了四个可能的参数位置
- path - 与路径模板一起使用,其中参数值实际上是操作 URL 的一部分。这不包括 API 的主机或基本路径。例如,在
/items/{itemId}
中,路径参数是 itemId
。
- query - 附加到 URL 的参数。例如,在
/items?id=###
中,查询参数是 id
。
- header - 作为请求一部分的自定义标头。请注意,RFC7230 指出标头名称不区分大小写。
- cookie - 用于将特定的 cookie 值传递给 API。
参数的序列化规则以两种方式之一指定。参数对象必须包含 content
字段或 schema
字段,但不能同时包含两者。有关将各种类型的值转换为字符串表示形式的讨论,请参阅附录 B。
公共固定字段
这些字段可以与 content
或 schema
一起使用。
固定字段 |
字段名 |
类型 |
名称 |
password |
必需。参数的名称。参数名称区分大小写。- 如果
in 是 "path" ,则 name 字段必须与路径字段中路径对象内出现的模板表达式相对应。有关更多信息,请参阅路径模板。 - 如果
in 是 "header" 且 name 字段是 "Accept" 、"Content-Type" 或 "Authorization" ,则应忽略参数定义。 - 对于所有其他情况,
name 对应于in 字段使用的参数名称。
|
in |
password |
必需。参数的位置。可能的值为 "query" 、"header" 、"path" 或 "cookie" 。 |
描述 |
password |
参数的简要描述。这可能包含使用示例。 CommonMark 语法 可以用于富文本表示。 |
必需 |
布尔值 |
确定此参数是否为强制性的。如果参数位置是 "path" ,则此字段是必需的,其值必须是 true 。否则,可以包含该字段,其默认值为 false 。 |
已弃用 |
布尔值 |
指定参数已弃用,应停止使用。默认值为 false 。 |
allowEmptyValue |
布尔值 |
如果为 true ,客户端可以传递一个零长度的字符串值来代替原本会被完全省略的参数,服务器应将此解释为参数未使用。默认值为 false 。如果使用了style ,并且如果行为是 n/a(无法序列化),则应忽略 allowEmptyValue 的值。此字段与参数的架构对象之间的交互是特定于实现的。此字段仅对 query 参数有效。不建议使用此字段,并且很可能会在以后的修订版本中删除。 |
此对象可以使用 规范扩展 进行扩展。
请注意,虽然如果 in
是 "header"
,则不禁止将 "Cookie"
作为 name
,但以这种方式定义 cookie 参数的效果是未定义的;请改用 in: "cookie"
。
用于 schema
的固定字段
对于更简单的场景,schema
和 style
可以描述参数的结构和语法。当与 schema
字段一起提供 example
或 examples
时,该示例应与指定的架构匹配,并遵循该参数的规定序列化策略。example
和 examples
字段是互斥的,如果存在其中任何一个,它将覆盖架构中的任何 example
。
对于 in: "cookie"
参数、在其值中使用 HTTP 标头参数(名称=值对,后跟 ;
)的 in: "header"
参数,或值可能包含非 URL 安全字符的 in: "header"
参数,不建议使用 schema
进行序列化;有关详细信息,请参阅附录 D。
固定字段 |
字段名 |
类型 |
样式 |
password |
描述如何根据参数值的类型对参数值进行序列化。默认值(基于 in 的值):对于 "query" - "form" ;对于 "path" - "simple" ;对于 "header" - "simple" ;对于 "cookie" - "form" 。 |
explode |
布尔值 |
当此值为 true 时,类型为 array 或 object 的参数值将为数组的每个值或映射的键值对生成单独的参数。对于其他类型的参数,此字段不起作用。当style 为 "form" 时,默认值为 true 。对于所有其他样式,默认值为 false 。请注意,尽管 false 是 deepObject 的默认值,但 false 与 deepObject 的组合是未定义的。 |
allowReserved |
布尔值 |
当此值为 true 时,参数值将使用RFC6570定义的保留扩展进行序列化,允许RFC3986 的保留字符集以及百分比编码的三元组保持不变地传递,同时仍然对所有其他不允许的字符(包括百分比编码三元组之外的 % )进行百分比编码。应用程序仍然负责对查询字符串中不允许的保留字符 ([ , ] , # ) 进行百分比编码,或者在 application/x-www-form-urlencoded 中具有特殊含义的字符 (- , & , + ) 进行百分比编码;有关详细信息,请参阅附录C和E。此字段仅适用于 in 值为 query 的参数。默认值为 false 。 |
schema |
架构对象 |
定义用于参数的类型的架构。 |
示例 |
任何 |
参数的潜在值示例;请参阅使用示例。 |
示例 |
Map[ string , 示例对象 | 引用对象] |
参数的潜在值示例;请参阅使用示例。 |
另请参阅附录 C:使用基于 RFC6570 的序列化,以获取其他指导。
用于 content
的固定字段
对于更复杂的场景,content
字段可以定义参数的媒体类型和架构,并给出其用法的示例。对于 in: "header"
和 in: "cookie"
参数,如果 schema
策略不适用,则建议将 content
与 text/plain
媒体类型一起使用。
固定字段 |
字段名 |
类型 |
content |
Map[string , 媒体类型对象] |
包含参数表示形式的映射。键是媒体类型,值描述它。该映射必须只包含一个条目。 |
样式值
为了支持序列化简单参数的常用方法,定义了一组 style
值。
style |
编码 |
in |
注释 |
matrix |
primitive , array , object |
path |
由 RFC6570 定义的路径样式参数 |
label |
primitive , array , object |
path |
由 RFC6570 定义的标签样式参数 |
simple |
primitive , array , object |
path , header |
由 RFC6570 定义的简单样式参数。此选项将 OpenAPI 2.0 中的 collectionFormat 替换为 csv 值。 |
form |
primitive , array , object |
query , cookie |
由 RFC6570 定义的表单样式参数。此选项将 OpenAPI 2.0 中的 collectionFormat 替换为 csv (当 explode 为 false 时) 或 multi (当 explode 为 true 时) 值。 |
spaceDelimited |
array , object |
query |
空格分隔的数组值或对象属性和值。此选项将 OpenAPI 2.0 中等于 ssv 的 collectionFormat 替换。 |
pipeDelimited |
array , object |
query |
管道分隔的数组值或对象属性和值。此选项将 OpenAPI 2.0 中等于 pipes 的 collectionFormat 替换。 |
deepObject |
object |
query |
允许使用表单参数表示具有标量属性的对象。未定义数组或对象属性的表示形式。 |
有关百分号编码的讨论,包括何时需要对分隔符进行百分号编码以及处理与百分号编码数据冲突的选项,请参见 附录 E。
样式示例
假设一个名为 color
的参数具有以下值之一
string -> "blue"
array -> ["blue", "black", "brown"]
object -> { "R": 100, "G": 200, "B": 150 }
下表显示了示例,如同 example
或 examples
关键字所示,每个值的不同序列化。
- 值 _empty_ 表示空字符串,与
allowEmptyValue
字段无关
- 标记为 _n/a_ 的组合的行为未定义
undefined
列替换了本规范先前版本中的 empty
列,以便更好地与 RFC6570 术语对齐,该术语将某些值(包括但不限于 null
)描述为具有特殊处理的“未定义”值;值得注意的是,空字符串 _不是_ 未定义的
- 对于
form
和非 RFC6570 查询字符串样式 spaceDelimited
、pipeDelimited
和 deepObject
,每个示例都以 ?
为前缀显示,就好像它是唯一的查询参数一样;有关从多个参数构造查询字符串的更多信息,请参见 附录 C,有关 form
和 cookie 参数的警告,请参见 附录 D
- 请注意,
?
前缀不适用于序列化 application/x-www-form-urlencoded
HTTP 消息体,并且在用于该上下文中时,必须删除或(如果手动构造字符串)不添加;有关更多信息,请参见 编码对象
- 这些示例根据 RFC6570 和 RFC3986 的要求进行百分号编码;有关百分号编码问题的全面讨论,包括为什么未编码的
|
(%7C
)、[
(%5B
) 和 ]
(%5D
) 在某些环境中似乎可以工作,尽管不符合要求,请参见 附录 E。
style |
explode |
undefined |
password |
array |
object |
matrix |
false |
;color |
;color=blue |
;color=blue,black,brown |
;color=R,100,G,200,B,150 |
matrix |
true |
;color |
;color=blue |
;color=blue;color=black;color=brown |
;R=100;G=200;B=150 |
label |
false |
. |
.blue |
.blue,black,brown |
.R,100,G,200,B,150 |
label |
true |
. |
.blue |
.blue.black.brown |
.R=100.G=200.B=150 |
simple |
false |
empty |
blue |
blue,black,brown |
R,100,G,200,B,150 |
simple |
true |
empty |
blue |
blue,black,brown |
R=100,G=200,B=150 |
form |
false |
?color= |
?color=blue |
?color=blue,black,brown |
?color=R,100,G,200,B,150 |
form |
true |
?color= |
?color=blue |
?color=blue&color=black&color=brown |
?R=100&G=200&B=150 |
spaceDelimited |
false |
不适用 |
不适用 |
?color=blue%20black%20brown |
?color=R%20100%20G%20200%20B%20150 |
spaceDelimited |
true |
不适用 |
不适用 |
不适用 |
不适用 |
pipeDelimited |
false |
不适用 |
不适用 |
?color=blue%7Cblack%7Cbrown |
?color=R%7C100%7CG%7C200%7CB%7C150 |
pipeDelimited |
true |
不适用 |
不适用 |
不适用 |
不适用 |
deepObject |
false |
不适用 |
不适用 |
不适用 |
不适用 |
deepObject |
true |
不适用 |
不适用 |
不适用 |
?color%5BR%5D=100&color%5BG%5D=200&color%5BB%5D=150 |
参数对象示例
带有 64 位整数数组的标头参数
{
"name": "token",
"in": "header",
"description": "token to be passed as a header",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "integer",
"format": "int64"
}
},
"style": "simple"
}
name: token
in: header
description: token to be passed as a header
required: true
schema:
type: array
items:
type: integer
format: int64
style: simple
字符串值的路径参数
{
"name": "username",
"in": "path",
"description": "username to fetch",
"required": true,
"schema": {
"type": "string"
}
}
name: username
in: path
description: username to fetch
required: true
schema:
type: string
字符串值的可选查询参数,允许通过重复查询参数来使用多个值
{
"name": "id",
"in": "query",
"description": "ID of the object to fetch",
"required": false,
"schema": {
"type": "array",
"items": {
"type": "string"
}
},
"style": "form",
"explode": true
}
name: id
in: query
description: ID of the object to fetch
required: false
schema:
type: array
items:
type: string
style: form
explode: true
自由格式的查询参数,允许特定类型的未定义参数
{
"in": "query",
"name": "freeForm",
"schema": {
"type": "object",
"additionalProperties": {
"type": "integer"
}
},
"style": "form"
}
in: query
name: freeForm
schema:
type: object
additionalProperties:
type: integer
style: form
使用 content
定义序列化的复杂参数
{
"in": "query",
"name": "coordinates",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["lat", "long"],
"properties": {
"lat": {
"type": "number"
},
"long": {
"type": "number"
}
}
}
}
}
}
in: query
name: coordinates
content:
application/json:
schema:
type: object
required:
- lat
- long
properties:
lat:
type: number
long:
type: number
请求主体对象
描述单个请求主体。
固定字段 |
字段名 |
类型 |
description |
password |
请求主体的简短描述。这可以包含使用示例。 CommonMark 语法 可用于富文本表示形式。 |
content |
Map[string , 媒体类型对象] |
必需。请求主体的内容。键是媒体类型或 媒体类型范围,值描述它。对于匹配多个键的请求,仅最具体的键适用。例如,"text/plain" 覆盖 "text/*" |
required |
布尔值 |
确定请求主体是否在请求中是必需的。默认为 false 。 |
此对象可以使用 规范扩展 进行扩展。
请求主体示例
带有引用架构定义的请求主体。
{
"description": "user to add to the system",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/User"
},
"examples": {
"user": {
"summary": "User Example",
"externalValue": "https://foo.bar/examples/user-example.json"
}
}
},
"application/xml": {
"schema": {
"$ref": "#/components/schemas/User"
},
"examples": {
"user": {
"summary": "User example in XML",
"externalValue": "https://foo.bar/examples/user-example.xml"
}
}
},
"text/plain": {
"examples": {
"user": {
"summary": "User example in Plain text",
"externalValue": "https://foo.bar/examples/user-example.txt"
}
}
},
"*/*": {
"examples": {
"user": {
"summary": "User example in other format",
"externalValue": "https://foo.bar/examples/user-example.whatever"
}
}
}
}
}
description: user to add to the system
content:
application/json:
schema:
$ref: '#/components/schemas/User'
examples:
user:
summary: User example
externalValue: https://foo.bar/examples/user-example.json
application/xml:
schema:
$ref: '#/components/schemas/User'
examples:
user:
summary: User example in XML
externalValue: https://foo.bar/examples/user-example.xml
text/plain:
examples:
user:
summary: User example in plain text
externalValue: https://foo.bar/examples/user-example.txt
'*/*':
examples:
user:
summary: User example in other format
externalValue: https://foo.bar/examples/user-example.whatever
每个媒体类型对象都为其键标识的媒体类型提供架构和示例。
当提供 example
或 examples
时,该示例应匹配指定的架构,并且格式应正确,如媒体类型及其编码所指定。example
和 examples
字段是互斥的,如果存在任何一个,则应覆盖架构中的任何 example
。有关指定示例的不同方法的进一步指导(包括非 JSON/YAML 值),请参见 使用示例。
固定字段 |
字段名 |
类型 |
schema |
架构对象 |
定义请求、响应、参数或标头内容的架构。 |
example |
任何 |
媒体类型的示例;请参见 使用示例。 |
examples |
Map[ string , 示例对象 | 引用对象] |
媒体类型的示例;请参见 使用示例。 |
encoding |
Map[string , 编码对象] |
属性名称及其编码信息之间的映射。键(即属性名称)必须作为属性存在于架构中。encoding 字段应仅适用于 请求主体对象,并且仅当媒体类型为 multipart 或 application/x-www-form-urlencoded 时。如果未为属性提供编码对象,则行为由编码对象的默认值确定。 |
此对象可以使用 规范扩展 进行扩展。
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/Pet"
},
"examples": {
"cat": {
"summary": "An example of a cat",
"value": {
"name": "Fluffy",
"petType": "Cat",
"color": "White",
"gender": "male",
"breed": "Persian"
}
},
"dog": {
"summary": "An example of a dog with a cat's name",
"value": {
"name": "Puma",
"petType": "Dog",
"color": "Black",
"gender": "Female",
"breed": "Mixed"
}
},
"frog": {
"$ref": "#/components/examples/frog-example"
}
}
}
}
application/json:
schema:
$ref: '#/components/schemas/Pet'
examples:
cat:
summary: An example of a cat
value:
name: Fluffy
petType: Cat
color: White
gender: male
breed: Persian
dog:
summary: An example of a dog with a cat's name
value:
name: Puma
petType: Dog
color: Black
gender: Female
breed: Mixed
frog:
$ref: '#/components/examples/frog-example'
文件上传的注意事项
与 OpenAPI 2.0 相比,OAS 3.x 中的 file
输入/输出内容使用与任何其他架构类型相同的语义描述。
与 OAS 3.0 相比,format
关键字对 OAS 3.1 中架构的内容编码没有影响。而是使用 JSON Schema 的 contentEncoding
和 contentMediaType
关键字。有关如何使用这些关键字对各种场景建模以及如何从之前的 format
用法迁移,请参见 使用二进制数据。
示例
以二进制 (octet-stream) 传输的内容可以省略 schema
# a PNG image as a binary file:
content:
image/png: {}
# an arbitrary binary file:
content:
application/octet-stream: {}
# arbitrary JSON without constraints beyond being syntactically valid:
content:
application/json: {}
这些示例适用于文件上传的输入有效负载或响应有效负载。
用于在 POST
操作中提交文件的 requestBody
可能如下例所示
requestBody:
content:
application/octet-stream: {}
此外,可以指定特定的媒体类型
# multiple, specific media types may be specified:
requestBody:
content:
# a binary file of type png or jpeg
image/jpeg: {}
image/png: {}
要上传多个文件,必须使用 multipart
媒体类型,如 示例:具有多个文件的多部分表单 中所示。
有关指导和示例(无论是否带有 encoding
字段),请参见 编码 x-www-form-urlencoded
媒体类型。
multipart
内容的特殊注意事项
有关进一步的指导和示例(无论是否带有 encoding
字段),请参见 编码 multipart
媒体类型。
编码对象
应用于单个架构属性的单个编码定义。有关将各种类型的值转换为字符串表示形式的讨论,请参见 附录 B。
属性与使用 Content-Disposition: form-data
的 name
参数的 multipart
部分相关,并且与使用查询字符串参数名称的 application/x-www-form-urlencoded
相关。在这两种情况下,它们的顺序都是实现定义的。
有关表单媒体类型的百分号编码问题的详细检查,请参见 附录 E。
公共固定字段
这些字段可以与下面下一节中定义的 RFC6570 样式的序列化字段一起使用,也可以不与它们一起使用。
固定字段 |
字段名 |
类型 |
contentType |
password |
用于编码特定属性的 Content-Type 。该值是以逗号分隔的列表,其中的每个元素都是特定的媒体类型(例如 image/png )或通配符媒体类型(例如 image/* )。默认值取决于属性类型,如下表所示。 |
headers |
Map[string , 标头对象 | 引用对象] |
允许将其他信息作为标头提供的映射。Content-Type 将单独描述,并且在本节中应忽略。如果请求主体媒体类型不是 multipart ,则应忽略此字段。 |
此对象可以使用 规范扩展 进行扩展。
contentType
的默认值如下,其中 contentEncoding
列中的 _n/a_ 表示 contentEncoding
的存在或值是无关紧要的
编码 |
如果冗余,有时可以省略(见下文) |
默认 contentType |
absent |
不适用 |
application/octet-stream |
password |
present |
application/octet-stream |
password |
absent |
text/plain |
number , integer 或 boolean |
不适用 |
text/plain |
object |
不适用 |
application/json |
array |
不适用 |
根据 items 架构的 type |
如何处理 null
的 type
值取决于如何序列化 null
值。如果完全省略 null
值,则 contentType
无关紧要。有关数据类型转换选项的讨论,请参见 附录 B。
RFC6570 样式序列化的固定字段
固定字段 |
字段名 |
类型 |
style |
password |
描述了如何根据属性值的类型对其进行序列化。有关 style 字段的详细信息,请参阅 参数对象。其行为遵循与 query 参数相同的值,包括默认值。请注意,查询字符串中使用的初始 ? 不在 application/x-www-form-urlencoded 消息体中使用,并且必须删除(如果使用 RFC6570 实现)或简单地不添加(如果手动构建字符串)。如果请求体的媒体类型不是 application/x-www-form-urlencoded 或 multipart/form-data ,则应忽略此字段。如果显式定义了值,则应忽略 contentType (隐式或显式)的值。 |
explode |
布尔值 |
当此值为 true 时,类型为 array 或 object 的属性值会为数组的每个值或映射的每个键值对生成单独的参数。对于其他类型的属性,此字段无效。当 style 为 "form" 时,默认值为 true 。对于所有其他样式,默认值为 false 。请注意,尽管 false 是 deepObject 的默认值,但 false 与 deepObject 的组合是未定义的。如果请求体的媒体类型不是 application/x-www-form-urlencoded 或 multipart/form-data ,则应忽略此字段。如果显式定义了值,则应忽略 contentType (隐式或显式)的值。 |
allowReserved |
布尔值 |
当此值为 true 时,参数值将使用 RFC6570 定义的保留扩展进行序列化,该扩展允许 RFC3986 的保留字符集,以及百分比编码的三元组保持不变,同时仍然对所有其他不允许的字符进行百分比编码(包括百分比编码三元组之外的 % )。应用程序仍然负责对 查询字符串中不允许([ 、] 、# )或在 application/x-www-form-urlencoded 中具有特殊含义(- 、& 、+ )的保留字符进行百分比编码;有关详细信息,请参阅附录 C 和 E。默认值为 false 。如果请求体的媒体类型不是 application/x-www-form-urlencoded 或 multipart/form-data ,则应忽略此字段。如果显式定义了值,则应忽略 contentType (隐式或显式)的值。 |
另请参阅 附录 C:使用基于 RFC6570 的实现,了解其他指导,包括由 RFC6570 的百分比编码规则和 multipart/form-data
媒体类型之间的交互引起的困难。
请注意,至少存在一个带有显式值的 style
、explode
或 allowReserved
等同于使用 in: "query"
参数对象的 schema
。缺少所有这三个字段等同于使用 content
,但媒体类型是在 contentType
中指定的,而不是通过媒体类型对象指定的。
要通过 RFC1866 使用表单 URL 编码提交内容,请在 请求体对象下的 媒体类型对象中使用 application/x-www-form-urlencoded
媒体类型。此配置意味着在将任何复杂对象序列化为字符串表示后,传递给服务器时,请求体必须按照 RFC1866 进行编码。
有关表单媒体类型的百分号编码问题的详细检查,请参见 附录 E。
当没有 encoding
字段时,序列化策略基于编码对象的默认值
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
id:
type: string
format: uuid
address:
# complex types are stringified to support RFC 1866
type: object
properties: {}
在此示例中,假设 id
为 f81d4fae-7dec-11d0-a765-00a0c91e6bf6
,并且美国式地址(带 ZIP+4)如下所示
{
"streetAddress": "123 Example Dr.",
"city": "Somewhere",
"state": "CA",
"zip": "99999+1234"
}
假设 JSON 值的最紧凑表示形式(删除了不必要的空格),我们期望看到以下请求体,其中空格字符已替换为 +
,+
、"
、{
和 }
已分别百分比编码为 %2B
、%22
、%7B
和 %7D
id=f81d4fae-7dec-11d0-a765-00a0c91e6bf6&address=%7B%22streetAddress%22:%22123+Example+Dr.%22,%22city%22:%22Somewhere%22,%22state%22:%22CA%22,%22zip%22:%2299999%2B1234%22%7D
请注意,根据 编码对象的默认行为,id
关键字被视为 text/plain
,并且按原样序列化。如果将其视为 application/json
,则序列化值将是包含引号的 JSON 字符串,该字符串将被百分比编码为 %22
。
以下是 id
参数(不带 address
)序列化为 application/json
而不是 text/plain
,然后按照 RFC1866 编码
id=%22f81d4fae-7dec-11d0-a765-00a0c91e6bf6%22
请注意,application/x-www-form-urlencoded
是一种文本格式,需要对任何二进制数据进行 base64 编码
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
name:
type: string
icon:
# The default with "contentEncoding" is application/octet-stream,
# so we need to set image media type(s) in the Encoding Object.
type: string
contentEncoding: base64url
encoding:
icon:
contentType: image/png, image/jpeg
给定名称为 example
和一个纯红色 2x2 像素 PNG 用于 icon
,这将生成一个请求体
name=example&icon=iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAABGdBTUEAALGPC_xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAqADAAQAAAABAAAAAgAAAADO0J6QAAAAEElEQVQIHWP8zwACTGCSAQANHQEDqtPptQAAAABJRU5ErkJggg%3D%3D
请注意,即使使用“URL 安全”的 contentEncoding: base64url
,末尾的 =
填充字符也需要进行百分比编码。某些 base64 解码实现可能能够使用不带 RFC4648 填充的字符串。但是,这不能保证,因此保留填充并依赖于百分比解码可能更具互操作性。
当以请求体的形式传输表单时,通常使用 multipart/form-data
作为 Content-Type
。与 OpenAPI 2.0 相比,使用 multipart
内容时,必须使用 schema
来定义操作的输入参数。这支持复杂结构以及支持多个文件上传的机制。
form-data
处理及其 name
参数对于 multipart/form-data
是强制性的 (RFC7578)。数组属性通过将相同的 name
应用于多个部分来处理,正如 RFC7578 建议的那样,用于为每个表单字段提供多个值。有关非 ASCII 部分名称的指导,请参阅 RFC7578。
各种其他 multipart
类型,最显著的是 multipart/mixed
(RFC2046) 既不要求也不禁止特定的 Content-Disposition
值,这意味着必须注意确保所有相关软件都支持使用的任何值。目前无法将架构属性与 multipart/mixed
等媒体类型中未命名、有序的部分关联起来,但是当 Content-Disposition: form-data
与 name
参数一起使用时,实现可以选择支持此类类型。
请注意,通常情况下,可以与 multipart
媒体类型一起使用的标头存在重大限制 (RFC2046) ,特别是 multi-part/form-data
(RFC7578)。
另请注意,对于 multipart/form-data
,Content-Transfer-Encoding
已被弃用 (RFC7578),其中二进制数据受支持,就像在 HTTP 中一样。
+为多部分字段使用 contentEncoding
等同于指定一个 编码对象,其 headers
字段包含 Content-Transfer-Encoding
,并且其架构要求使用 contentEncoding
中使用的值。+如果 contentEncoding
用于具有包含 Content-Transfer-Encoding
的 headers
字段且架构不允许使用 contentEncoding
中的值的编码对象的多部分字段,则序列化和解析的结果是未定义的。
请注意,正如在 使用二进制数据中所述,如果编码对象的 contentType
(无论是显式设置还是通过其默认值规则隐式设置)与模式对象中的 contentMediaType
不一致,则应忽略 contentMediaType
。因此,并且由于编码对象的 contentType
默认规则不考虑模式对象的 contentMediaType
,因此不建议将 contentMediaType
与编码对象一起使用。
有关表单媒体类型的百分号编码问题的详细检查,请参见 附录 E。
当不使用 encoding
字段时,编码由编码对象的默认值确定
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
id:
# default for primitives without a special format is text/plain
type: string
format: uuid
profileImage:
# default for string with binary format is `application/octet-stream`
type: string
format: binary
addresses:
# default for arrays is based on the type in the `items`
# subschema, which is an object, so `application/json`
type: array
items:
$ref: '#/components/schemas/Address'
使用 encoding
,我们可以为二进制数据设置更具体的类型,或者为复杂值设置非 JSON 格式。我们还可以描述每个部分的标头
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
id:
# default is `text/plain`
type: string
format: uuid
addresses:
# default based on the `items` subschema would be
# `application/json`, but we want these address objects
# serialized as `application/xml` instead
description: addresses in XML format
type: array
items:
$ref: '#/components/schemas/Address'
profileImage:
# default is application/octet-stream, but we can declare
# a more specific image type or types
type: string
format: binary
encoding:
addresses:
# require XML Content-Type in utf-8 encoding
# This is applied to each address part corresponding
# to each address in he array
contentType: application/xml; charset=utf-8
profileImage:
# only accept png or jpeg
contentType: image/png, image/jpeg
headers:
X-Rate-Limit-Limit:
description: The number of allowed requests in the current period
schema:
type: integer
根据 RFC7578,单个表单字段的多个文件使用每个文件部分的相同名称(在本例中为 file
)上传
requestBody:
content:
multipart/form-data:
schema:
properties:
# The property name 'file' will be used for all files.
file:
type: array
items: {}
正如在 编码对象的 contentType
字段文档 中看到的那样,items
的空架构表示媒体类型为 application/octet-stream
。
响应对象
操作预期响应的容器。该容器将 HTTP 响应代码映射到预期的响应。
该文档不一定需要涵盖所有可能的 HTTP 响应代码,因为它们可能事先未知。但是,文档应涵盖成功的操作响应和任何已知的错误。
default
可用作响应对象中未单独涵盖的响应对象的所有 HTTP 代码的默认值。
响应对象必须包含至少一个响应代码,如果仅提供一个响应代码,则它应该是成功操作调用的响应。
固定字段 |
字段名 |
类型 |
default |
响应对象 | 引用对象 |
除为特定 HTTP 响应代码声明的响应之外的响应文档。使用此字段来涵盖未声明的响应。 |
模式化字段
字段模式 |
字段名 |
类型 |
HTTP 状态代码 |
响应对象 | 引用对象 |
任何 HTTP 状态码 都可以用作属性名称,但每个状态码只能有一个属性,用于描述该 HTTP 状态码的预期响应。为了在 JSON 和 YAML 之间兼容,此字段必须用引号括起来(例如,“200”)。要定义一系列响应代码,此字段可以包含大写通配符 X 。例如,2XX 表示 200 到 299 之间的所有响应代码。仅允许以下范围定义:1XX 、2XX 、3XX 、4XX 和 5XX 。如果使用显式代码定义了响应,则该显式代码定义优先于该代码的范围定义。 |
此对象可以使用 规范扩展 进行扩展。
响应对象示例
一个成功操作的 200 响应,以及其他操作的默认响应(暗示错误)
{
"200": {
"description": "a pet to be returned",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Pet"
}
}
}
},
"default": {
"description": "Unexpected error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
}
}
}
'200':
description: a pet to be returned
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
default:
description: Unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorModel'
响应对象
描述来自 API 操作的单个响应,包括基于响应的运行时静态 links
到操作。
固定字段 |
字段名 |
类型 |
描述 |
password |
必需。响应的描述。 CommonMark 语法 可以用于富文本表示。 |
标头 |
Map[string , 标头对象 | 引用对象] |
将标头名称映射到其定义。 RFC7230 指出标头名称不区分大小写。 如果响应标头使用名称 "Content-Type" 定义,则应忽略它。 |
内容 |
Map[string , 媒体类型对象] |
包含潜在响应负载描述的映射。 键是媒体类型或 媒体类型范围,值描述它。 对于匹配多个键的响应,仅适用最具体的键。 例如,"text/plain" 会覆盖 "text/*" |
链接 |
Map[string , 链接对象 | 引用对象] |
可以从响应跟踪的操作链接的映射。映射的键是链接的短名称,遵循 组件对象 名称的命名约束。 |
此对象可以使用 规范扩展 进行扩展。
响应对象示例
复杂类型数组的响应
{
"description": "A complex object array response",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/VeryComplexType"
}
}
}
}
}
description: A complex object array response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/VeryComplexType'
字符串类型的响应
{
"description": "A simple string response",
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
}
}
description: A simple string response
content:
text/plain:
schema:
type: string
带有标头的纯文本响应
{
"description": "A simple string response",
"content": {
"text/plain": {
"schema": {
"type": "string"
},
"example": "whoa!"
}
},
"headers": {
"X-Rate-Limit-Limit": {
"description": "The number of allowed requests in the current period",
"schema": {
"type": "integer"
}
},
"X-Rate-Limit-Remaining": {
"description": "The number of remaining requests in the current period",
"schema": {
"type": "integer"
}
},
"X-Rate-Limit-Reset": {
"description": "The number of seconds left in the current period",
"schema": {
"type": "integer"
}
}
}
}
description: A simple string response
content:
text/plain:
schema:
type: string
example: 'whoa!'
headers:
X-Rate-Limit-Limit:
description: The number of allowed requests in the current period
schema:
type: integer
X-Rate-Limit-Remaining:
description: The number of remaining requests in the current period
schema:
type: integer
X-Rate-Limit-Reset:
description: The number of seconds left in the current period
schema:
type: integer
没有返回值的响应
{
"description": "object created"
}
description: object created
回调对象
与父操作相关的可能带外回调的映射。映射中的每个值都是一个 路径项对象,它描述了 API 提供程序可能启动的一组请求以及预期的响应。 用于标识路径项对象的键值是一个表达式,在运行时进行评估,以识别用于回调操作的 URL。
要描述来自 API 提供程序的独立于另一个 API 调用的传入请求,请使用 webhooks
字段。
模式化字段
字段模式 |
字段名 |
类型 |
{表达式} |
路径项对象 |
用于定义回调请求和预期响应的路径项对象。 有一个完整示例可用。 |
此对象可以使用 规范扩展 进行扩展。
键表达式
标识 路径项对象 的键是一个 运行时表达式,可以在运行时 HTTP 请求/响应的上下文中对其进行评估,以识别用于回调请求的 URL。 一个简单的示例可能是 $request.body#/url
。 但是,使用 运行时表达式 可以访问完整的 HTTP 消息。 这包括访问 JSON 指针 RFC6901 可以引用的任何正文部分。
例如,给定以下 HTTP 请求
POST /subscribe/myevent?queryUrl=https://clientdomain.com/stillrunning HTTP/1.1
Host: example.org
Content-Type: application/json
Content-Length: 188
{
"failedUrl": "https://clientdomain.com/failed",
"successUrls": [
"https://clientdomain.com/fast",
"https://clientdomain.com/medium",
"https://clientdomain.com/slow"
]
}
产生以下结果
201 Created
Location: https://example.org/subscription/1
以下示例显示了各种表达式的评估方式,假设回调操作具有名为 eventType
的路径参数和名为 queryUrl
的查询参数。
回调对象示例
以下示例使用用户提供的 queryUrl
查询字符串参数来定义回调 URL。 这类似于 webhook,但不同之处在于回调仅在发送 queryUrl
的初始请求时发生。
myCallback:
'{$request.query.queryUrl}':
post:
requestBody:
description: Callback payload
content:
application/json:
schema:
$ref: '#/components/schemas/SomePayload'
responses:
'200':
description: callback successfully processed
以下示例显示了一个回调,其中服务器是硬编码的,但查询字符串参数是从请求正文中的 id
和 email
属性填充的。
transactionCallback:
'http://notificationServer.com?transactionId={$request.body#/id}&email={$request.body#/email}':
post:
requestBody:
description: Callback payload
content:
application/json:
schema:
$ref: '#/components/schemas/SomePayload'
responses:
'200':
description: callback successfully processed
示例对象
一个对象,将内部或外部示例值与基本 summary
和 description
元数据分组在一起。此对象通常用于名为 examples
(复数)的字段中,并且是较旧的 example
(单数)字段的 可引用替代方案,这些字段不支持引用或元数据。
示例允许演示 OpenAPI 中属性、参数和对象的使用情况。
固定字段 |
字段名 |
类型 |
摘要 |
password |
示例的简短描述。 |
描述 |
password |
示例的详细描述。CommonMark 语法可以用于富文本表示。 |
值 |
任何 |
嵌入的文字示例。value 字段和 externalValue 字段是互斥的。要表示无法在 JSON 或 YAML 中自然表示的媒体类型的示例,请使用字符串值来包含示例,并在必要时进行转义。 |
外部值 |
password |
标识文字示例的 URI。 这提供了引用无法轻易包含在 JSON 或 YAML 文档中的示例的功能。value 字段和 externalValue 字段是互斥的。 请参阅解析 相对引用 的规则。 |
此对象可以使用 规范扩展 进行扩展。
在所有情况下,示例值应与关联值的架构兼容。工具实现可以选择自动验证兼容性,如果示例值不兼容,则拒绝该值。
使用示例
示例对象可以在 参数对象 和 媒体类型对象 中使用。在这两个对象中,都是通过 examples
(复数)字段完成的。但是,还有其他几种提供示例的方法:example
(单数)字段,它与这两个对象中的 examples
互斥,以及 架构对象 中出现的两个关键字(已弃用的单数 example
和当前的复数 examples
,它接受示例数组),这些关键字出现在这两个对象的 schema
字段中。这些字段中的每一个都有略有不同的注意事项。
架构对象的字段用于显示示例值,而不考虑它们如何格式化为参数或在媒体类型表示形式中。examples
数组是 JSON 架构的一部分,是包含架构对象中示例的首选方式,而保留 example
纯粹是为了与 OpenAPI 规范的旧版本兼容。
参数或媒体类型对象中的互斥字段用于显示示例值,这些示例值应既匹配架构,又格式化为它们将以序列化参数的形式或在媒体类型表示形式中显示。确切的序列化和编码由参数对象中的各种字段或媒体类型对象的 编码对象 确定。由于使用这些字段的示例表示数据的最终序列化形式,它们应覆盖相应架构对象中的任何 example
。
参数或媒体类型对象中的单数 example
字段对于简单示例来说是简洁方便的,但与在 examples
下使用示例对象相比没有任何其他优势。
某些示例不能直接在 JSON 或 YAML 中表示。对于提供示例的所有三种方式,这些都可以显示为字符串值,其中包含使字符串在组成 OpenAPI 描述的文档的 JSON 或 YAML 格式中有效的任何必要转义。使用示例对象,这些值也可以通过 externalValue
字段处理。
示例对象示例
在请求正文中
requestBody:
content:
'application/json':
schema:
$ref: '#/components/schemas/Address'
examples:
foo:
summary: A foo example
value:
foo: bar
bar:
summary: A bar example
value:
bar: baz
application/xml:
examples:
xmlExample:
summary: This is an example in XML
externalValue: https://example.org/examples/address-example.xml
text/plain:
examples:
textExample:
summary: This is a text example
externalValue: https://foo.bar/examples/address-example.txt
在参数中
parameters:
- name: zipCode
in: query
schema:
type: string
format: zip-code
examples:
zip-example:
$ref: '#/components/examples/zip-example'
在响应中
responses:
'200':
description: your car appointment has been booked
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
examples:
confirmation-success:
$ref: '#/components/examples/confirmation-success'
JSON 字符串的两种不同用法
首先,一个请求或响应正文,它只是一个 JSON 字符串(不是包含字符串的对象)
"application/json": {
"schema": {
"type": "string"
},
"examples": {
"jsonBody": {
"description": "A body of just the JSON string \"json\"",
"value": "json"
}
}
}
application/json:
schema:
type: string
examples:
jsonBody:
description: 'A body of just the JSON string "json"'
value: json
在上面的示例中,我们可以直接按原样显示 JSON 字符串(或任何 JSON 值),而不是将序列化的 JSON 值塞进 JSON 字符串,这将看起来像 "\"json\""
。
相比之下,在 URL 样式表单正文中编码的 JSON 字符串
"application/x-www-form-urlencoded": {
"schema": {
"type": "object",
"properties": {
"jsonValue": {
"type": "string"
}
}
},
"encoding": {
"jsonValue": {
"contentType": "application/json"
}
},
"examples": {
"jsonFormValue": {
"description": "The JSON string \"json\" as a form value",
"value": "jsonValue=%22json%22"
}
}
}
application/x-www-form-urlencoded:
schema:
type: object
properties:
jsonValue:
type: string
encoding:
jsonValue:
contentType: application/json
examples:
jsonFormValue:
description: 'The JSON string "json" as a form value'
value: jsonValue=%22json%22
在此示例中,JSON 字符串必须先进行序列化,然后才能将其编码为 URL 表单值,因此该示例包括作为 JSON 序列化一部分的引号,然后将其 URL 百分比编码。
链接对象
链接对象表示响应可能的运行时链接。链接的存在并不能保证调用者能够成功调用它,而是提供了响应和其他操作之间的已知关系和遍历机制。
与动态链接(即在响应有效负载中提供的链接)不同,OAS 链接机制不需要运行时响应中的链接信息。
为了计算链接并提供执行它们的说明,运行时表达式 用于访问操作中的值,并在调用链接的操作时将其用作参数。
固定字段 |
字段名 |
类型 |
operationRef |
password |
对 OAS 操作的 URI 引用。此字段与 operationId 字段互斥,并且必须指向 操作对象。可以使用相对 operationRef 值在 OpenAPI 描述中查找现有的 操作对象。 |
operationId |
password |
现有的可解析 OAS 操作的名称,如唯一的 operationId 定义的那样。此字段与 operationRef 字段互斥。 |
参数 |
Map[string , Any | {expression}] |
一个映射,表示要传递给使用 operationId 指定或通过 operationRef 标识的操作的参数。键是要使用的参数名称(可以选择使用参数位置进行限定,例如,路径中的 id 参数为 path.id ),而值可以是常量或要评估并传递给链接的操作的表达式。 |
请求正文 |
Any | {expression} |
当调用目标操作时,要用作请求正文的文字值或 {expression}。 |
描述 |
password |
链接的描述。CommonMark 语法 可以用于富文本表示。 |
服务器 |
服务器对象 |
目标操作要使用的服务器对象。 |
此对象可以使用 规范扩展 进行扩展。
必须使用 operationRef
或 operationId
标识链接的操作。标识或引用的操作必须是唯一的,并且在 operationId
的情况下,它必须在 OpenAPI 描述 (OAD) 的范围内解析。由于可能存在名称冲突,因此对于多文档 OAD,首选 operationRef
语法。但是,由于操作的使用取决于 路径对象 中的 URL 路径模板,因此无法明确解析 OAD 中多次引用的任何 路径项对象 的操作。在这种模棱两可的情况下,结果行为是实现定义的,并可能导致错误。
请注意,无法为 parameters
提供与运行时表达式语法匹配的常量值。可能会出现参数名称歧义的情况,例如 name: "id", in: "path"
和 name: "path.id", in: "query"
;这**不建议**,并且行为是实现定义的,但是实现**应该**优先选择限定解释(path.id
作为路径参数),因为名称始终可以被限定以消除歧义(例如,对于查询参数使用 query.path.id
)。
示例
计算请求操作的链接,其中 $request.path.id
用于将请求参数传递到链接的操作。
paths:
/users/{id}:
parameters:
- name: id
in: path
required: true
description: the user identifier, as userId
schema:
type: string
get:
responses:
'200':
description: the user being returned
content:
application/json:
schema:
type: object
properties:
uuid: # the unique user id
type: string
format: uuid
links:
address:
# the target link operationId
operationId: getUserAddress
parameters:
# get the `id` field from the request path parameter named `id`
userid: $request.path.id
# the path item of the linked operation
/users/{userid}/address:
parameters:
- name: userid
in: path
required: true
description: the user identifier, as userId
schema:
type: string
# linked operation
get:
operationId: getUserAddress
responses:
'200':
description: the user's address
当运行时表达式求值失败时,不会将任何参数值传递给目标操作。
响应主体中的值可以用来驱动链接的操作。
links:
address:
operationId: getUserAddressByUUID
parameters:
# get the `uuid` field from the `uuid` field in the response body
userUuid: $response.body#/uuid
客户端自行决定是否遵循所有链接。仅凭关系的存在并不能保证权限或成功调用该链接的能力。
operationRef
示例
由于可能无法引用 operationId
(operationId
是 Operation Object 中的可选字段),因此也可以通过相对 operationRef
进行引用
links:
UserRepositories:
# returns array of '#/components/schemas/repository'
operationRef: '#/paths/~12.0~1repositories~1%7Busername%7D/get'
parameters:
username: $response.body#/username
或 URI operationRef
links:
UserRepositories:
# returns array of '#/components/schemas/repository'
operationRef: https://na2.gigantic-server.com/#/paths/~12.0~1repositories~1%7Busername%7D/get
parameters:
username: $response.body#/username
请注意,在使用 operationRef
时,使用 JSON 指针时必须使用*转义斜杠*,并且在使用 JSON 指针作为 URI 片段时,必须将 {
和 }
分别 URL 编码为 %7B
和 %7D
。
运行时表达式
运行时表达式允许基于实际 API 调用中 HTTP 消息中才可用的信息来定义值。 Link Objects 和 Callback Objects 使用此机制。
运行时表达式由以下 ABNF 语法定义
expression = "$url" / "$method" / "$statusCode" / "$request." source / "$response." source
source = header-reference / query-reference / path-reference / body-reference
header-reference = "header." token
query-reference = "query." name
path-reference = "path." name
body-reference = "body" ["#" json-pointer ]
json-pointer = *( "/" reference-token )
reference-token = *( unescaped / escaped )
unescaped = %x00-2E / %x30-7D / %x7F-10FFFF
; %x2F ('/') and %x7E ('~') are excluded from 'unescaped'
escaped = "~" ( "0" / "1" )
; representing '~' and '/', respectively
name = *( CHAR )
token = 1*tchar
tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "."
/ "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
此处,json-pointer
取自 RFC6901,char
取自 RFC7159,token
取自 RFC7230。
name
标识符区分大小写,而 token
不区分大小写。
下表提供了运行时表达式示例以及它们在值中的使用示例
示例
源位置 |
示例表达式 |
备注 |
HTTP 方法 |
$method |
$method 的允许值将是 HTTP 操作的值。 |
请求的媒体类型 |
$request.header.accept |
|
请求参数 |
$request.path.id |
请求参数必须在父操作的 parameters 部分中声明,否则无法对其进行求值。这包括请求标头。 |
请求主体属性 |
$request.body#/user/uuid |
在接受有效负载的操作中,可以引用 requestBody 的部分或整个主体。 |
请求 URL |
$url |
|
响应值 |
$response.body#/status |
在返回有效负载的操作中,可以引用响应主体的部分或整个主体。 |
响应标头 |
$response.header.Server |
仅提供单个标头值 |
运行时表达式保留被引用值的类型。 可以通过用 {}
花括号包围表达式将表达式嵌入到字符串值中。
描述 HTTP 响应和 multipart
表示形式中的各个部分的单个标头;有关可以描述哪些标头的限制,请参阅相关的 Response 对象 和 Encoding 对象 文档。
Header 对象遵循 Parameter 对象的结构,包括根据是否存在 schema
或 content
来确定其序列化策略,并具有以下更改
- 不得指定
name
,它在相应的 headers
映射中给出。
- 不得指定
in
,它隐式地位于 header
中。
- 受位置影响的所有特征必须适用于
header
的位置(例如,style
)。这意味着不得使用 allowEmptyValue
和 allowReserved
,并且如果使用 style
,则必须限制为 "simple"
。
公共固定字段
这些字段可以与 content
或 schema
一起使用。
固定字段 |
字段名 |
类型 |
描述 |
password |
标头的简短描述。 这可以包含使用示例。 CommonMark 语法 可以用于富文本表示。 |
必需 |
布尔值 |
确定此标头是否是强制性的。 默认值为 false 。 |
已弃用 |
布尔值 |
指定该标头已弃用,应停止使用。默认值为 false 。 |
此对象可以使用 规范扩展 进行扩展。
用于 schema
的固定字段
对于更简单的场景,schema
和 style
可以描述标头的结构和语法。当与 schema
字段一起提供 example
或 examples
时,示例必须遵循标头的指定序列化策略。
对于其值中带有参数(跟随 ;
的 name=value 对)或值可能包含非 URL 安全字符的标头,不建议使用 schema
进行序列化;有关详细信息,请参阅 附录 D。
当与 schema
字段一起提供 example
或 examples
时,示例**应该**与指定的 schema 相匹配,并遵循标头的指定序列化策略。example
和 examples
字段是互斥的,如果存在任何一个,它**应该*覆盖 schema 中的任何 example
。
固定字段 |
字段名 |
类型 |
样式 |
password |
描述标头值将如何序列化。 默认值(也是标头的唯一合法值)是 "simple" 。 |
explode |
布尔值 |
如果此值为 true,则 array 或 object 类型的标头值会生成一个标头,其值是数组项或映射的键值对的逗号分隔列表,请参阅 样式示例。 对于其他数据类型,此字段无效。默认值为 false 。 |
schema |
Schema 对象 | Reference 对象 |
定义标头所用类型的 schema。 |
示例 |
任何 |
标头的潜在值示例;请参阅 使用示例。 |
示例 |
Map[ string , 示例对象 | 引用对象] |
标头的潜在值示例;请参阅 使用示例。 |
另请参阅附录 C:使用基于 RFC6570 的序列化,以获取其他指导。
用于 content
的固定字段
对于更复杂的场景,content
字段可以定义标头的媒体类型和 schema,并给出其使用示例。对于 schema
策略不适用的标头,建议将 content
与 text/plain
媒体类型一起使用。
固定字段 |
字段名 |
类型 |
content |
Map[string , 媒体类型对象] |
包含标头的表示形式的映射。 键是媒体类型,值描述它。 该映射必须仅包含一个条目。 |
类型为 integer
的简单标头
"X-Rate-Limit-Limit": {
"description": "The number of allowed requests in the current period",
"schema": {
"type": "integer"
}
}
X-Rate-Limit-Limit:
description: The number of allowed requests in the current period
schema:
type: integer
要求存在一个强 ETag
标头(其值以 "
开头而不是 W/
)。请注意 content
的使用,因为使用 schema
和 style
将要求将 "
百分比编码为 %22
"ETag": {
"required": true,
"content": {
"text/plain": {
"schema": {
"type": "string",
"pattern": "^\""
}
}
}
}
ETag:
required: true
content:
text/plain:
schema:
type: string
pattern: ^"
Tag 对象
向 Operation 对象 使用的单个标签添加元数据。 每个在 Operation 对象实例中定义的标签都必须有一个 Tag 对象,这不是强制性的。
固定字段 |
字段名 |
类型 |
名称 |
password |
必需。 标签的名称。 |
描述 |
password |
标签的描述。 CommonMark 语法 可以用于富文本表示。 |
externalDocs |
外部文档对象 |
此标签的其他外部文档。 |
此对象可以使用 规范扩展 进行扩展。
Tag 对象示例
{
"name": "pet",
"description": "Pets operations"
}
name: pet
description: Pets operations
Reference 对象
一个简单的对象,允许引用 OpenAPI 描述中的其他组件,包括内部和外部。
$ref
字符串值包含一个 URI RFC3986,用于标识被引用的值。
请参阅解析 相对引用 的规则。
固定字段 |
字段名 |
类型 |
$ref |
password |
必需。 引用标识符。 这必须采用 URI 的形式。 |
摘要 |
password |
一个简短的摘要,默认情况下,**应该**覆盖被引用组件的摘要。 如果被引用的对象类型不允许 summary 字段,则此字段无效。 |
描述 |
password |
一个描述,默认情况下,**应该**覆盖被引用组件的描述。 CommonMark 语法 可以用于富文本表示。 如果被引用的对象类型不允许 description 字段,则此字段无效。 |
此对象不能使用其他属性进行扩展,并且任何添加的属性都应被忽略。
请注意,对其他属性的限制是 Reference 对象和包含 $ref
关键字的 Schema 对象 之间的区别。
Reference 对象示例
{
"$ref": "#/components/schemas/Pet"
}
$ref: '#/components/schemas/Pet'
相对 Schema 文档示例
{
"$ref": "Pet.json"
}
$ref: Pet.yaml
具有嵌入式 Schema 的相对文档示例
{
"$ref": "definitions.json#/Pet"
}
$ref: definitions.yaml#/Pet
架构对象
Schema 对象允许定义输入和输出数据类型。 这些类型可以是对象,也可以是基本类型和数组。 此对象是 JSON Schema Specification Draft 2020-12 的超集。 空的 schema(允许验证任何实例)可以用布尔值 true
表示,而允许不验证任何实例的 schema 可以用布尔值 false
表示。
有关关键字的更多信息,请参阅 JSON Schema Core 和 JSON Schema Validation。
除非另有说明,否则关键字定义遵循 JSON Schema 的定义,并且不添加任何其他语义; 这包括 $schema
、$id
、$ref
和 $dynamicRef
等关键字是 URI 而不是 URL。 如果 JSON Schema 指示行为由应用程序定义(例如对于注释),则 OAS 还会将语义的定义推迟到使用 OpenAPI 文档的应用程序。
JSON Schema 关键字
OpenAPI Schema 对象 方言定义为需要 OAS 基础词汇,以及 JSON Schema Specification Draft 2020-12 通用元 schema 中指定的词汇表。
此规范版本的 OpenAPI Schema 对象方言由 URI https://spec.openapis.org.cn/oas/3.1/dialect/base
标识(即“OAS 方言模式 ID”)。
以下关键字取自 JSON Schema 规范,但其定义已由 OAS 扩展。
- description - CommonMark 语法 可以用于富文本表示。
- format - 更多细节请参阅 数据类型格式。在依赖 JSON Schema 定义的格式的同时,OAS 提供了一些额外的预定义格式。
除了构成 OAS 方言的 JSON Schema 关键字外,Schema 对象还支持来自任何其他词汇表的关键字,或完全任意的属性。
JSON Schema 实现可以选择将 OpenAPI 规范的基本词汇表定义的关键字视为未知关键字,因为它以 false
的 $vocabulary
值包含在 OAS 方言中。OAS 基本词汇表包含以下关键字
固定字段 |
字段名 |
类型 |
discriminator |
Discriminator 对象 |
添加了对多态性的支持。判别器用于确定有效负载期望满足的一组模式中的哪一个。有关更多详细信息,请参阅组合和继承。 |
xml |
XML 对象 |
此属性可能仅用于属性模式。它对根模式没有影响。添加额外元数据来描述此属性的 XML 表示形式。 |
externalDocs |
外部文档对象 |
此模式的额外外部文档。 |
example |
任何 |
一个自由格式的字段,用于包含此模式实例的示例。为了表示不能在 JSON 或 YAML 中自然表示的示例,可以使用字符串值来包含示例,并在必要时进行转义。
已弃用: example 字段已被弃用,推荐使用 JSON Schema 的 examples 关键字。不鼓励使用 example ,此规范的后续版本可能会将其删除。 |
此对象可以使用规范扩展进行扩展,但如上所述,额外的属性可能会省略此对象中的 x-
前缀。
带注释的扩展验证
JSON Schema Draft 2020-12 支持收集注释,包括将无法识别的关键字视为注释。OAS 实现可以使用此类注释,包括扩展(未被识别为声明的 JSON Schema 词汇表的一部分),作为进一步验证的基础。请注意,JSON Schema Draft 2020-12 不要求扩展使用 x-
前缀。
非验证约束关键字
format
关键字(当使用默认的 format-annotation 词汇表时)以及 contentMediaType
、contentEncoding
和 contentSchema
关键字定义了对数据的约束,但被视为注释而不是直接验证。扩展验证是强制执行这些约束的一种方法。
验证 readOnly
和 writeOnly
readOnly
和 writeOnly
关键字是注释,因为 JSON Schema 不知道正在验证的数据的使用方式。对这些关键字的验证可以通过检查注释、读取或写入方向以及(如果相关)该字段的当前值来完成。JSON Schema Validation Draft 2020-12 §9.4 定义了这些关键字的预期行为,包括资源(描述为“拥有权限”)可以忽略 readOnly
字段或将其视为错误。
同时是必需和只读的字段就是一个例子,说明在 PUT 操作中忽略 readOnly: true
约束是有益的,特别是当值没有改变时。这允许在 GET 操作中正确地要求该字段,并且仍然在 PUT 操作中使用相同的表示形式和模式。即使只读字段不是必需的,剥离它们对于客户端来说也是一个负担,尤其是在 JSON 数据复杂或深度嵌套时。
请注意,readOnly
的行为与此规范的 3.0 版本指定的行为不同。
数据建模技术
组合和继承(多态性)
OpenAPI 规范允许使用 JSON Schema 的 allOf
关键字组合和扩展模型定义,实际上提供了模型组合。allOf
接受对象定义的数组,这些定义独立地进行验证,但共同组成一个对象。
虽然组合提供了模型的可扩展性,但它并不意味着模型之间存在层次结构。为了支持多态性,OpenAPI 规范添加了discriminator
字段。使用时,discriminator
指示属性的名称,该属性提示期望哪个模式定义来验证模型的结构。因此,discriminator
字段必须是必需的字段。有两种方法可以为继承实例定义判别器的值。
通用(模板)数据结构
实现可以使用 JSON Schema 的动态引用功能来支持定义通用或模板数据结构。
$dynamicAnchor
标识一组可能的模式(包括默认占位符模式),$dynamicRef
可以解析为这些模式。
$dynamicRef
解析为其从模式入口点到引用的路径上遇到的第一个匹配的 $dynamicAnchor
,如 JSON Schema 规范中所述。
下面的“Schema 对象示例”部分中包含一个示例,并且可以在 Learn OpenAPI 网站的“动态引用”页面上找到更多信息。
带注释的枚举
Schema 对象的 enum
关键字不允许将描述或其他信息与各个值关联。
实现可以支持识别 oneOf
或 anyOf
,其中关键字数组中的每个子模式由 const
关键字和诸如 title
或 description
之类的注释组成,作为具有附加信息的枚举类型。此模式超出 JSON Schema 要求的确切行为是实现定义的。
XML 建模
当将 JSON 定义转换为 XML 时,xml 字段允许额外的定义。XML 对象包含有关可用选项的更多信息。
指定模式方言
对于工具来说,能够确定任何给定资源希望使用哪个方言或元模式进行处理非常重要:JSON Schema Core、JSON Schema Validation、OpenAPI Schema 方言或某些自定义元模式。
$schema
关键字可以出现在任何作为模式资源根的 Schema 对象中,并且如果存在,则必须用于确定在处理模式时应使用哪个方言。这允许使用符合 JSON Schema 的其他草案(而不是默认的 Draft 2020-12 支持)的 Schema 对象。工具必须支持OAS 方言模式 ID,并且可能支持 $schema
的其他值。
为了允许为 OAS 文档中包含的所有 Schema 对象使用不同的默认 $schema
值,可以在OpenAPI 对象中设置 jsonSchemaDialect
值。如果未设置此默认值,则必须对这些 Schema 对象使用 OAS 方言模式 ID。资源根 Schema 对象中的 $schema
值始终会覆盖任何默认值。
对于未设置 $schema
的独立 JSON Schema 文档,或者对于 不是 完整文档的 OpenAPI 描述文档中的 Schema 对象,应假设该方言为 OAS 方言。但是,为了获得最大的互操作性,建议 OpenAPI 描述作者在此类文档中通过 $schema
显式设置方言。
Schema 对象示例
基本示例
{
"type": "string",
"format": "email"
}
type: string
format: email
简单模型
{
"type": "object",
"required": ["name"],
"properties": {
"name": {
"type": "string"
},
"address": {
"$ref": "#/components/schemas/Address"
},
"age": {
"type": "integer",
"format": "int32",
"minimum": 0
}
}
}
type: object
required:
- name
properties:
name:
type: string
address:
$ref: '#/components/schemas/Address'
age:
type: integer
format: int32
minimum: 0
带有 Map/Dictionary 属性的模型
对于简单的字符串到字符串映射
{
"type": "object",
"additionalProperties": {
"type": "string"
}
}
type: object
additionalProperties:
type: string
对于字符串到模型映射
{
"type": "object",
"additionalProperties": {
"$ref": "#/components/schemas/ComplexModel"
}
}
type: object
additionalProperties:
$ref: '#/components/schemas/ComplexModel'
带有注释的枚举的模型
{
"oneOf": [
{
"const": "RGB",
"title": "Red, Green, Blue",
"description": "Specify colors with the red, green, and blue additive color model"
},
{
"const": "CMYK",
"title": "Cyan, Magenta, Yellow, Black",
"description": "Specify colors with the cyan, magenta, yellow, and black subtractive color model"
}
]
}
oneOf:
- const: RGB
title: Red, Green, Blue
description: Specify colors with the red, green, and blue additive color model
- const: CMYK
title: Cyan, Magenta, Yellow, Black
description: Specify colors with the cyan, magenta, yellow, and black subtractive color model
带有示例的模型
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
},
"required": ["name"],
"examples": [
{
"name": "Puma",
"id": 1
}
]
}
type: object
properties:
id:
type: integer
format: int64
name:
type: string
required:
- name
examples:
- name: Puma
id: 1
带有组合的模型
{
"components": {
"schemas": {
"ErrorModel": {
"type": "object",
"required": ["message", "code"],
"properties": {
"message": {
"type": "string"
},
"code": {
"type": "integer",
"minimum": 100,
"maximum": 600
}
}
},
"ExtendedErrorModel": {
"allOf": [
{
"$ref": "#/components/schemas/ErrorModel"
},
{
"type": "object",
"required": ["rootCause"],
"properties": {
"rootCause": {
"type": "string"
}
}
}
]
}
}
}
}
components:
schemas:
ErrorModel:
type: object
required:
- message
- code
properties:
message:
type: string
code:
type: integer
minimum: 100
maximum: 600
ExtendedErrorModel:
allOf:
- $ref: '#/components/schemas/ErrorModel'
- type: object
required:
- rootCause
properties:
rootCause:
type: string
支持多态性的模型
{
"components": {
"schemas": {
"Pet": {
"type": "object",
"discriminator": {
"propertyName": "petType"
},
"properties": {
"name": {
"type": "string"
},
"petType": {
"type": "string"
}
},
"required": ["name", "petType"]
},
"Cat": {
"description": "A representation of a cat. Note that `Cat` will be used as the discriminating value.",
"allOf": [
{
"$ref": "#/components/schemas/Pet"
},
{
"type": "object",
"properties": {
"huntingSkill": {
"type": "string",
"description": "The measured skill for hunting",
"default": "lazy",
"enum": ["clueless", "lazy", "adventurous", "aggressive"]
}
},
"required": ["huntingSkill"]
}
]
},
"Dog": {
"description": "A representation of a dog. Note that `Dog` will be used as the discriminating value.",
"allOf": [
{
"$ref": "#/components/schemas/Pet"
},
{
"type": "object",
"properties": {
"packSize": {
"type": "integer",
"format": "int32",
"description": "the size of the pack the dog is from",
"default": 0,
"minimum": 0
}
},
"required": ["packSize"]
}
]
}
}
}
}
components:
schemas:
Pet:
type: object
discriminator:
propertyName: petType
properties:
name:
type: string
petType:
type: string
required:
- name
- petType
Cat: # "Cat" will be used as the discriminating value
description: A representation of a cat
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
properties:
huntingSkill:
type: string
description: The measured skill for hunting
enum:
- clueless
- lazy
- adventurous
- aggressive
required:
- huntingSkill
Dog: # "Dog" will be used as the discriminating value
description: A representation of a dog
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
properties:
packSize:
type: integer
format: int32
description: the size of the pack the dog is from
default: 0
minimum: 0
required:
- packSize
通用数据结构模型
{
"components": {
"schemas": {
"genericArrayComponent": {
"$id": "fully_generic_array",
"type": "array",
"items": {
"$dynamicRef": "#generic-array"
},
"$defs": {
"allowAll": {
"$dynamicAnchor": "generic-array"
}
}
},
"numberArray": {
"$id": "array_of_numbers",
"$ref": "fully_generic_array",
"$defs": {
"numbersOnly": {
"$dynamicAnchor": "generic-array",
"type": "number"
}
}
},
"stringArray": {
"$id": "array_of_strings",
"$ref": "fully_generic_array",
"$defs": {
"stringsOnly": {
"$dynamicAnchor": "generic-array",
"type": "string"
}
}
},
"objWithTypedArray": {
"$id": "obj_with_typed_array",
"type": "object",
"required": ["dataType", "data"],
"properties": {
"dataType": {
"enum": ["string", "number"]
}
},
"oneOf": [{
"properties": {
"dataType": {"const": "string"},
"data": {"$ref": "array_of_strings"}
}
}, {
"properties": {
"dataType": {"const": "number"},
"data": {"$ref": "array_of_numbers"}
}
}]
}
}
}
}
components:
schemas:
genericArrayComponent:
$id: fully_generic_array
type: array
items:
$dynamicRef: '#generic-array'
$defs:
allowAll:
$dynamicAnchor: generic-array
numberArray:
$id: array_of_numbers
$ref: fully_generic_array
$defs:
numbersOnly:
$dynamicAnchor: generic-array
type: number
stringArray:
$id: array_of_strings
$ref: fully_generic_array
$defs:
stringsOnly:
$dynamicAnchor: generic-array
type: string
objWithTypedArray:
$id: obj_with_typed_array
type: object
required:
- dataType
- data
properties:
dataType:
enum:
- string
- number
oneOf:
- properties:
dataType:
const: string
data:
$ref: array_of_strings
- properties:
dataType:
const: number
data:
$ref: array_of_numbers
Discriminator 对象
当请求正文或响应有效负载可能是多种不同模式之一时,判别器对象会给出关于文档预期模式的提示。此提示可用于帮助序列化、反序列化和验证。判别器对象通过隐式或显式地将命名属性的可能值与备用模式关联来实现此目的。
请注意,discriminator
不得更改模式的验证结果。
固定字段 |
字段名 |
类型 |
propertyName |
password |
必需。有效负载中将保存判别值的属性的名称。此属性在有效负载模式中应为必需,因为当该属性不存在时的行为是未定义的。 |
mapping |
Map[string , string ] |
一个对象,用于保存有效负载值和模式名称或 URI 引用之间的映射。 |
此对象可以使用 规范扩展 进行扩展。
使用判别器对象的条件
仅当使用复合关键字 oneOf
、anyOf
、allOf
之一时,判别器对象才是合法的。
在 oneOf
和 anyOf
用例中,当这些关键字与 discriminator
相邻时,必须显式列出所有可能的模式。
为了避免冗余,可以将判别器添加到父模式定义中,并且所有通过 allOf
构造在父模式上构建的模式都可以用作备用模式。
discriminator
的 allOf
形式仅对非验证用例有用;使用此形式的 discriminator
对父模式进行验证不会搜索子模式或以任何方式在验证中使用它们。这是因为 discriminator
不能更改验证结果,并且没有标准的 JSON Schema 关键字将父模式连接到子模式。
上述未描述的任何 oneOf
、anyOf
、allOf
和 discriminator
的配置的行为是未定义的。
将值映射到模式的选项
propertyName
中命名的属性的值用作组件对象下关联模式的名称,除非该值存在 mapping
。mapping
条目将特定的属性值映射到不同的模式组件名称,或映射到由 URI 标识的模式。当使用隐式或显式模式组件名称时,不考虑内联 oneOf
或 anyOf
子模式。mapping
值既是有效的模式名称又是有效的相对 URI 引用的行为是实现定义的,但建议将其视为模式名称。为了确保所有实现都将模糊值(例如 "foo"
)视为相对 URI 引用,作者必须使用 "."
路径段(例如 "./foo"
)作为前缀。
映射键必须是字符串值,但工具可能会将响应值转换为字符串进行比较。但是,此类转换的确切性质是实现定义的。
示例
对于这些示例,假设所有模式都在 OAD 的入口文档中;有关在引用的文档中处理 discriminator
的信息,请参阅解析隐式连接。
在 OAS 3.x 中,响应有效负载可以被描述为恰好是任意数量的类型之一。
MyResponseType:
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Lizard'
这意味着,通过验证,有效载荷必须与 Cat
、Dog
或 Lizard
所描述的模式之一完全匹配。 反序列化 oneOf
可能是一项代价高昂的操作,因为它需要确定哪个模式与有效载荷匹配,从而确定应该使用哪个模式进行反序列化。 anyOf
模式也存在这个问题。 可以使用 discriminator
作为“提示”来提高匹配模式的选择效率。 discriminator
字段不会改变 oneOf
的验证结果,它只能帮助提高反序列化的效率并提供更好的错误消息。 我们可以指定确切的字段来告诉我们期望哪个模式匹配实例
MyResponseType:
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Lizard'
discriminator:
propertyName: petType
现在的期望是,响应有效载荷中必须存在一个名为 petType
的属性,并且该值将对应于 OpenAPI 描述中定义的模式的名称。 因此,响应有效载荷
{
"id": 12345,
"petType": "Cat"
}
将指示期望 Cat
模式与此有效载荷匹配。
在 discriminator
字段的值与模式名称不匹配或无法进行隐式映射的情况下,可以使用可选的 mapping
定义
MyResponseType:
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Lizard'
- $ref: https://gigantic-server.com/schemas/Monster/schema.json
discriminator:
propertyName: petType
mapping:
dog: '#/components/schemas/Dog'
monster: https://gigantic-server.com/schemas/Monster/schema.json
这里,dog
的区分值将映射到模式 #/components/schemas/Dog
,而不是默认(隐式)值 #/components/schemas/dog
。 如果区分值与隐式或显式映射不匹配,则无法确定模式,并且验证应该失败。
当与 anyOf
结构结合使用时,鉴别器的使用可以避免序列化器/反序列化器在多个模式可以满足单个有效载荷时的歧义。
此示例显示了 allOf
的用法,它避免了在父模式中引用所有子模式的需要
components:
schemas:
Pet:
type: object
required:
- petType
properties:
petType:
type: string
discriminator:
propertyName: petType
mapping:
dog: Dog
Cat:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
# all other properties specific to a `Cat`
properties:
name:
type: string
Dog:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
# all other properties specific to a `Dog`
properties:
bark:
type: string
Lizard:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
# all other properties specific to a `Lizard`
properties:
lovesRocks:
type: boolean
针对 Pet
模式进行验证,像这样的有效载荷
{
"petType": "Cat",
"name": "Misty"
}
将指示期望 #/components/schemas/Cat
模式匹配。 同样,此有效载荷
{
"petType": "dog",
"bark": "soft"
}
将映射到 #/components/schemas/Dog
,因为 mapping
元素中的 dog
条目映射到 Dog
,后者是 #/components/schemas/Dog
的模式名称。
XML 对象
一个元数据对象,允许进行更精细的 XML 模型定义。
当使用数组时,XML 元素名称不会被推断(对于单数/复数形式),并且应该使用 name
字段来添加该信息。 请参阅预期行为的示例。
固定字段 |
字段名 |
类型 |
名称 |
password |
替换用于描述模式属性的元素/属性的名称。 当在 items 中定义时,它将影响列表中各个 XML 元素的名称。 当与 type 定义为 "array" (在 items 之外) 一起定义时,当且仅当 wrapped 为 true 时,它才会影响包装元素。 如果 wrapped 为 false ,它将被忽略。 |
命名空间 |
password |
命名空间定义的 URI。 值必须采用非相对 URI 的形式。 |
前缀 |
password |
用于 名称 的前缀。 |
属性 |
布尔值 |
声明属性定义是否转换为属性而不是元素。 默认值为 false 。 |
包装 |
布尔值 |
仅可用于数组定义。 表示数组是包装的(例如,<books><book/><book/></books> )还是未包装的(<book/><book/> )。 默认值为 false 。 该定义仅在与 type 定义为 "array" (在 items 之外) 一起定义时才生效。 |
此对象可以使用 规范扩展 进行扩展。
namespace
字段旨在匹配 XML 命名空间 的语法,但有一些注意事项
- 本规范的 3.1.0、3.0.3 和更早版本错误地使用了术语“绝对 URI”而不是“非相对 URI”,因此使用包含片段的命名空间的作者应仔细检查工具支持。
- XML 允许但不鼓励使用相对 URI 引用,而本规范完全禁止它们。
- XML 1.1 允许使用 IRI (RFC3987) 作为命名空间,并指定比较命名空间时无需进行任何编码或解码,这意味着为满足本规范的 URI 语法要求而编码的 IRI 不能与原样的 IRI 进行比较。
XML 对象示例
以下每个示例都表示为简洁起见而省略的 模式对象 中 properties
关键字的值。 properties
值的 JSON 和 YAML 表示形式之后是一个为显示的单个属性生成的 XML 表示形式示例。
无 XML 元素
基本字符串属性
{
"animals": {
"type": "string"
}
}
animals:
type: string
<animals>...</animals>
基本字符串数组属性(wrapped
默认为 false
)
{
"animals": {
"type": "array",
"items": {
"type": "string"
}
}
}
animals:
type: array
items:
type: string
<animals>...</animals>
<animals>...</animals>
<animals>...</animals>
XML 名称替换
{
"animals": {
"type": "string",
"xml": {
"name": "animal"
}
}
}
animals:
type: string
xml:
name: animal
<animal>...</animal>
XML 属性、前缀和命名空间
在此示例中,显示了完整的模型定义。
{
"Person": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32",
"xml": {
"attribute": true
}
},
"name": {
"type": "string",
"xml": {
"namespace": "https://example.com/schema/sample",
"prefix": "sample"
}
}
}
}
}
Person:
type: object
properties:
id:
type: integer
format: int32
xml:
attribute: true
name:
type: string
xml:
namespace: https://example.com/schema/sample
prefix: sample
<Person id="123">
<sample:name xmlns:sample="https://example.com/schema/sample">example</sample:name>
</Person>
XML 数组
更改元素名称
{
"animals": {
"type": "array",
"items": {
"type": "string",
"xml": {
"name": "animal"
}
}
}
}
animals:
type: array
items:
type: string
xml:
name: animal
<animal>value</animal>
<animal>value</animal>
外部 name
字段对 XML 没有影响
{
"animals": {
"type": "array",
"items": {
"type": "string",
"xml": {
"name": "animal"
}
},
"xml": {
"name": "aliens"
}
}
}
animals:
type: array
items:
type: string
xml:
name: animal
xml:
name: aliens
<animal>value</animal>
<animal>value</animal>
即使数组被包装,如果没有显式定义名称,内部和外部都将使用相同的名称
{
"animals": {
"type": "array",
"items": {
"type": "string"
},
"xml": {
"wrapped": true
}
}
}
animals:
type: array
items:
type: string
xml:
wrapped: true
<animals>
<animals>value</animals>
<animals>value</animals>
</animals>
为了克服上面示例中的命名问题,可以使用以下定义
{
"animals": {
"type": "array",
"items": {
"type": "string",
"xml": {
"name": "animal"
}
},
"xml": {
"wrapped": true
}
}
}
animals:
type: array
items:
type: string
xml:
name: animal
xml:
wrapped: true
<animals>
<animal>value</animal>
<animal>value</animal>
</animals>
影响内部和外部名称
{
"animals": {
"type": "array",
"items": {
"type": "string",
"xml": {
"name": "animal"
}
},
"xml": {
"name": "aliens",
"wrapped": true
}
}
}
animals:
type: array
items:
type: string
xml:
name: animal
xml:
name: aliens
wrapped: true
<aliens>
<animal>value</animal>
<animal>value</animal>
</aliens>
如果我们更改外部元素但没有更改内部元素
{
"animals": {
"type": "array",
"items": {
"type": "string"
},
"xml": {
"name": "aliens",
"wrapped": true
}
}
}
animals:
type: array
items:
type: string
xml:
name: aliens
wrapped: true
<aliens>
<aliens>value</aliens>
<aliens>value</aliens>
</aliens>
安全方案对象
定义可由操作使用的安全方案。
支持的方案包括 HTTP 身份验证、API 密钥(作为标头、cookie 参数或查询参数)、相互 TLS(使用客户端证书)、OAuth2 的常见流程(隐式、密码、客户端凭据和授权代码),如 RFC6749 和 [[OpenID-Connect-Core]] 中定义的那样。 请注意,截至 2020 年,隐式流程即将被 OAuth 2.0 安全最佳实践弃用。 建议大多数用例使用带有 PKCE 的授权代码授权流程。
固定字段 |
字段名 |
适用于 |
类型 |
类型 |
password |
任何 |
必需。 安全方案的类型。 有效值包括 "apiKey" 、"http" 、"mutualTLS" 、"oauth2" 、"openIdConnect" 。 |
描述 |
password |
任何 |
安全方案的描述。 CommonMark 语法可以用于富文本表示。 |
名称 |
password |
apiKey |
必需。 要使用的标头、查询或 cookie 参数的名称。 |
位置 |
password |
apiKey |
必需。 API 密钥的位置。 有效值包括 "query" 、"header" 或 "cookie" 。 |
方案 |
password |
http |
必需。 要在 RFC7235 中定义的授权标头中使用的 HTTP 身份验证方案的名称。 所使用的值应该在 IANA 身份验证方案注册表中注册。 该值不区分大小写,如 RFC7235 中定义的那样。 |
持有者格式 |
password |
http ("bearer" ) |
提示客户端如何格式化持有者令牌。 持有者令牌通常由授权服务器生成,因此此信息主要用于文档目的。 |
流程 |
OAuth 流程对象 |
oauth2 |
必需。 一个对象,其中包含支持的流程类型的配置信息。 |
OpenID Connect URL |
password |
openIdConnect |
必需。 用于发现 [[OpenID-Connect-Discovery]] 提供程序元数据的 众所周知的 URL。 |
此对象可以使用 规范扩展 进行扩展。
安全方案对象示例
基本身份验证示例
{
"type": "http",
"scheme": "basic"
}
type: http
scheme: basic
API 密钥示例
{
"type": "apiKey",
"name": "api-key",
"in": "header"
}
type: apiKey
name: api-key
in: header
JWT 持有者示例
{
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT"
}
type: http
scheme: bearer
bearerFormat: JWT
MutualTLS 示例
{
"type": "mutualTLS",
"description": "Cert must be signed by example.com CA"
}
type: mutualTLS
description: Cert must be signed by example.com CA
隐式 OAuth2 示例
{
"type": "oauth2",
"flows": {
"implicit": {
"authorizationUrl": "https://example.com/api/oauth/dialog",
"scopes": {
"write:pets": "modify pets in your account",
"read:pets": "read your pets"
}
}
}
}
type: oauth2
flows:
implicit:
authorizationUrl: https://example.com/api/oauth/dialog
scopes:
write:pets: modify pets in your account
read:pets: read your pets
OAuth 流程对象
允许配置支持的 OAuth 流程。
固定字段 |
字段名 |
类型 |
隐式 |
OAuth 流程对象 |
OAuth 隐式流程的配置 |
密码 |
OAuth 流程对象 |
OAuth 资源所有者密码流程的配置 |
客户端凭据 |
OAuth 流程对象 |
OAuth 客户端凭据流程的配置。 在 OpenAPI 2.0 中以前称为 application 。 |
授权代码 |
OAuth 流程对象 |
OAuth 授权代码流程的配置。 在 OpenAPI 2.0 中以前称为 accessCode 。 |
此对象可以使用 规范扩展 进行扩展。
OAuth 流程对象
受支持的 OAuth 流程的配置详细信息
固定字段 |
字段名 |
适用于 |
类型 |
授权 URL |
password |
oauth2 ("implicit" , "authorizationCode" ) |
必需。 用于此流程的授权 URL。 这必须采用 URL 的形式。 OAuth2 标准要求使用 TLS。 |
令牌 URL |
password |
oauth2 ("password" , "clientCredentials" , "authorizationCode" ) |
必需。 用于此流程的令牌 URL。 这必须采用 URL 的形式。 OAuth2 标准要求使用 TLS。 |
刷新 URL |
password |
oauth2 |
用于获取刷新令牌的 URL。 这必须采用 URL 的形式。 OAuth2 标准要求使用 TLS。 |
范围 |
Map[string , string ] |
oauth2 |
必需。 OAuth2 安全方案的可用范围。 范围名称与其简短描述之间的映射。 该映射可以为空。 |
此对象可以使用 规范扩展 进行扩展。
OAuth 流程对象示例
{
"type": "oauth2",
"flows": {
"implicit": {
"authorizationUrl": "https://example.com/api/oauth/dialog",
"scopes": {
"write:pets": "modify pets in your account",
"read:pets": "read your pets"
}
},
"authorizationCode": {
"authorizationUrl": "https://example.com/api/oauth/dialog",
"tokenUrl": "https://example.com/api/oauth/token",
"scopes": {
"write:pets": "modify pets in your account",
"read:pets": "read your pets"
}
}
}
}
type: oauth2
flows:
implicit:
authorizationUrl: https://example.com/api/oauth/dialog
scopes:
write:pets: modify pets in your account
read:pets: read your pets
authorizationCode:
authorizationUrl: https://example.com/api/oauth/dialog
tokenUrl: https://example.com/api/oauth/token
scopes:
write:pets: modify pets in your account
read:pets: read your pets
安全要求对象
列出执行此操作所需的安全方案。 每个属性使用的名称必须与 组件对象下的 安全方案中声明的安全方案相对应。
安全要求对象可以引用多个安全方案,在这种情况下,必须满足所有方案才能授权请求。 这支持需要多个查询参数或 HTTP 标头来传递安全信息的场景。
当 security
字段在 OpenAPI 对象或 操作对象上定义,并且包含多个安全要求对象时,只需满足列表中的一项即可授权请求。 这支持 API 允许多个独立的安全性方案的场景。
一个空的安全要求对象 ({}
) 表示支持匿名访问。
模式化字段
字段模式 |
字段名 |
类型 |
{名称} |
[string ] |
每个名称必须与在 组件对象下的 安全方案中声明的安全方案相对应。 如果安全方案的类型为 "oauth2" 或 "openIdConnect" ,则该值是执行所需的范围名称列表,如果授权不需要指定的范围,则该列表可以为空。 对于其他安全方案类型,数组可以包含执行所需的角色名称列表,但在带内没有以其他方式定义或交换。 |
安全要求对象示例
另请参阅 附录 F:在引用文档中解析安全要求,了解在多文档 OpenAPI 描述中使用安全要求对象的示例。
非 OAuth2 安全要求
{
"api_key": []
}
api_key: []
OAuth2 安全要求
{
"petstore_auth": ["write:pets", "read:pets"]
}
petstore_auth:
- write:pets
- read:pets
可选 OAuth2 安全
可选 OAuth2 安全,如 OpenAPI 对象或 操作对象中所定义
{
"security": [
{},
{
"petstore_auth": ["write:pets", "read:pets"]
}
]
}
security:
- {}
- petstore_auth:
- write:pets
- read:pets
规范扩展
虽然 OpenAPI 规范试图适应大多数用例,但可以在某些点添加额外的数据来扩展规范。
扩展属性以模式化字段的形式实现,这些字段始终以 x-
为前缀。
字段模式 |
字段名 |
类型 |
^x- |
任何 |
允许扩展 OpenAPI Schema。字段名称必须以 x- 开头,例如 x-internal-id 。以 x-oai- 和 x-oas- 开头的字段名称保留给 OpenAPI 倡议 定义的用途。该值可以是任何有效的 JSON 值(null 、原始类型、数组或对象)。 |
OpenAPI 倡议维护着几个 [[OpenAPI-Registry|扩展注册表]],包括 单个扩展关键字 和 扩展关键字命名空间 的注册表。
扩展是证明规范中提议的添加项可行性的最佳方法之一。因此,建议将实现设计为可扩展的,以支持社区实验。
对任何一个扩展的支持都是可选的,对一个扩展的支持并不意味着对其他扩展的支持。
安全过滤
OpenAPI 规范中的某些对象可能会被声明并保持为空,或者被完全删除,即使它们本质上是 API 文档的核心。
这样做的原因是允许对文档进行额外的访问控制层。虽然不是规范本身的一部分,但某些库可能会选择根据某种形式的身份验证/授权来允许访问文档的某些部分。
以下是两个示例
- 路径对象 可以存在但为空。这可能违反直觉,但这可能会告诉查看者他们到了正确的位置,但无法访问任何文档。他们仍然至少可以访问 信息对象,其中可能包含有关身份验证的更多信息。
- 路径项对象 可以为空。在这种情况下,查看者会知道路径存在,但无法查看其任何操作或参数。这与从 路径对象 中隐藏路径本身不同,因为用户会知道它的存在。这允许文档提供程序精细地控制查看者可以看到的内容。
安全注意事项
OpenAPI 描述使用 JSON、YAML 和 JSON Schema 的组合,因此共享它们的安全注意事项。
此外,OpenAPI 描述被各种工具用于许多不同的目的进行处理,例如客户端代码生成、文档生成、服务器端路由和 API 测试。OpenAPI 描述作者必须考虑 OpenAPI 描述可能被使用的场景风险。
安全方案
OpenAPI 描述描述了用于保护其定义的资源的安全方案。可用的安全方案提供不同程度的保护。诸如数据的敏感性和安全漏洞的潜在影响等因素应指导 API 资源的安全方案选择。某些安全方案,如基本身份验证和 OAuth 隐式流,支持与现有 API 的兼容性。但是,它们包含在 OpenAPI 中并不构成对其使用的认可,特别是对于高度敏感的数据或操作。
处理外部资源
OpenAPI 描述可能包含对外部资源的引用,这些引用可能会被使用工具自动解引用。外部资源可能托管在不同的不受信任的域上。
处理引用循环
OpenAPI 描述中的引用可能会导致循环。工具必须检测和处理循环以防止资源耗尽。
Markdown 和 HTML 清理
某些字段允许使用 Markdown,其中可以包含包括脚本的 HTML。工具负责适当地清理 Markdown。
附录 A:修订历史
版本 |
日期 |
注释 |
3.1.1 |
2024-10-24 |
OpenAPI 规范 3.1.1 的补丁版本 |
3.1.0 |
2021-02-15 |
发布 OpenAPI 规范 3.1.0 |
3.1.0-rc1 |
2020-10-08 |
3.1 规范的 rc1 |
3.1.0-rc0 |
2020-06-18 |
3.1 规范的 rc0 |
3.0.4 |
2024-10-24 |
OpenAPI 规范 3.0.4 的补丁版本 |
3.0.3 |
2020-02-20 |
OpenAPI 规范 3.0.3 的补丁版本 |
3.0.2 |
2018-10-08 |
OpenAPI 规范 3.0.2 的补丁版本 |
3.0.1 |
2017-12-06 |
OpenAPI 规范 3.0.1 的补丁版本 |
3.0.0 |
2017-07-26 |
发布 OpenAPI 规范 3.0.0 |
3.0.0-rc2 |
2017-06-16 |
3.0 规范的 rc2 |
3.0.0-rc1 |
2017-04-27 |
3.0 规范的 rc1 |
3.0.0-rc0 |
2017-02-28 |
3.0 规范的实现者草案 |
2.0 |
2015-12-31 |
将 Swagger 2.0 捐赠给 OpenAPI 倡议 |
2.0 |
2014-09-08 |
发布 Swagger 2.0 |
1.2 |
2014-03-14 |
正式文档的初始发布。 |
1.1 |
2012-08-22 |
发布 Swagger 1.1 |
1.0 |
2011-08-10 |
Swagger 规范的首次发布 |
附录 B:数据类型转换
将类型化数据序列化为纯文本(可能发生在 text/plain
消息体或 multipart
部分中,以及 URL 查询字符串或消息体中的 application/x-www-form-urlencoded
格式中),涉及到大量实现或应用程序定义的行为。
Schema 对象 基于 JSON Schema 数据模型 验证数据,该模型仅识别四种原始数据类型:字符串(仅作为 UTF-8 广泛互操作)、数字、布尔值和 null
。值得注意的是,整数不是与其他数字不同的类型,其中 type: "integer"
是数学上定义的便利性,而不是基于任何字符串表示形式中是否存在小数点。
参数对象、标头对象 和 编码对象 提供了控制如何排列来自数组或对象类型的值的功能。它们还可以用于控制如何进一步编码字符串以避免保留或非法字符。但是,没有通用的规范用于将架构验证的非 UTF-8 原始数据类型(或整个数组或对象)转换为字符串。
以下两种情况确实提供了基于标准的指导:
- RFC3987 提供了将非 Unicode 字符串转换为 UTF-8 的指导,特别是在 URI 的上下文中(并且扩展到使用相同编码规则的表单媒体类型)
- RFC6570 指定了哪些值(包括但不限于
null
)被认为是未定义的,因此在基于该规范序列化时在扩展过程中会进行特殊处理。
RFC6570 的实现通常具有自己的转换非字符串值的约定,但这些是特定于实现的,并且不是由 RFC 本身定义的。这是 OpenAPI 规范将这些转换保留为实现定义的原因之一:它允许使用 RFC6570 的实现,而不管它们如何选择执行转换。
为了更精确地控制数字、布尔值和 null
(或 RFC6570 认为未定义的其他值)的序列化,可以将模式定义为 type: "string"
并使用 pattern
、enum
、format
和其他关键字进行约束,以传达应用程序必须如何在架构验证之前预转换其数据。生成的字符串不需要任何进一步的类型转换。
format
关键字可以协助序列化。某些格式(例如 date-time
)是明确的,而其他格式(例如 格式注册表 中的 decimal
)不太清楚。但是,必须谨慎使用 format
以确保所有相关工具都支持特定的格式,因为无法识别的格式将被忽略。
要求输入为预格式化的、经过架构验证的字符串也提高了往返互操作性,因为并非所有编程语言和环境都支持相同的数据类型。
附录 C:使用基于 RFC6570 的序列化
序列化在三种场景中根据 RFC6570 URI 模板进行定义
对象 |
条件 |
参数对象 |
当存在 schema 时 |
Header 对象 |
当存在 schema 时 |
编码对象 |
当为 application/x-www-form-urlencoded 编码,并且使用 style 、explode 或 allowReserved 中的任何一个时 |
此规范的实现可以使用 RFC6570 的实现来执行变量扩展,但是,一些注意事项适用。
请注意,当使用 style: "form"
RFC6570 扩展来生成 application/x-www-form-urlencoded
HTTP 消息体时,必须删除为满足 URI 查询字符串语法而产生的 ?
前缀。
当使用 style
和类似的关键字来生成 multipart/form-data
正文时,查询字符串名称放置在 Content-Disposition
部分标头的 name
参数中,值放置在相应的部分正文中;不使用 ?
、=
和 &
字符。请注意,虽然 RFC7578 允许在“文件名”中使用 [[RFC3986]] 百分比编码,但它没有另外解决格式内百分比编码的使用。RFC7578 详细讨论了 multipart/form-data
的字符集和编码问题,建议 OpenAPI 描述作者在决定使用基于 RFC6570 的序列化与此媒体类型之前仔细阅读此指南。
另请注意,并非所有 RFC6570 的实现都支持所有四个级别的运算符,而所有这些级别都是完全支持 OpenAPI 规范的使用所必需的。使用支持级别较低的实现将需要额外手动构造 URI 模板以解决限制。
字段和 RFC6570 运算符之间的等效关系
某些字段值转换为 RFC6570 运算符(或缺少运算符)
字段 |
值 |
等效项 |
style |
"简单" |
不适用 |
style |
"矩阵" |
; 前缀运算符 |
style |
"标签" |
. 前缀运算符 |
style |
"表单" |
? 前缀运算符 |
allowReserved |
false |
不适用 |
allowReserved |
true |
+ 前缀运算符 |
explode |
false |
不适用 |
explode |
true |
* 修饰符后缀 |
多个 style: "form"
参数等效于使用 ?
前缀运算符的单个 RFC6570 变量列表。
parameters:
- name: foo
in: query
schema:
type: object
explode: true
- name: bar
in: query
schema:
type: string
此示例等效于 RFC6570 的 {?foo*,bar}
,而不是 {?foo*}{&bar}
。后者存在问题,因为如果未定义 foo
,结果将是无效的 URI。&
前缀运算符在参数对象中没有等效项。
请注意,RFC6570 没有规定超出 explode
所处理的单层之外的复合值的行为。对于没有明确规定行为的对象或数组的使用结果,由具体实现来定义。
参数值中的分隔符
RFC6570 扩展使用的分隔符,例如用于将数组或对象值与 style: "simple"
连接的 ,
,只要 allowReserved
为 false
,都会自动进行百分比编码。请注意,由于 RFC6570 没有定义基于 URI 模板解析变量的方法,因此用户必须先按分隔符拆分值,然后再对可能包含分隔符字符的值进行百分比解码。
当 allowReserved
为 true
时,百分比编码(在用分隔符连接值之前)和百分比解码(在按分隔符拆分后)都必须在正确的时间手动完成。
有关处理 style
值(没有 RFC6570 等效项)的分隔符的其他指导,请参见附录 E,这些值在用作分隔符时已经需要进行百分比编码。
非 RFC6570 字段值和组合
没有直接 RFC6570 等效项的配置也应该根据 RFC6570 进行处理。实现可以(基于 allowReserved
)使用 RFC6570 常规或保留扩展为各个名称和值创建一个正确分隔的 URI 模板。
这包括
- 样式
pipeDelimited
、spaceDelimited
和 deepObject
,它们根本没有等效项
- 样式
form
与 allowReserved: true
的组合,这是不允许的,因为一次只能使用一个前缀运算符
- 任何不是合法的 RFC6570 变量名称的参数名称
Parameter Object 的 name
字段的语法比 RFC6570 变量名称语法 宽松得多。参数名称中包含 RFC6570 允许的变量字符集之外的字符,必须在将其用于 URI 模板之前进行百分比编码。
示例
假设我们想在表单查询字符串中使用以下数据,其中 formulas
是 exploded 的,而 words
不是
formulas:
a: x+y
b: x/y
c: x^y
words:
- math
- is
- fun
RFC6570 等效扩展
此 Parameter Object 数组使用常规 style: "form"
扩展,完全受 RFC6570 支持
parameters:
- name: formulas
in: query
schema:
type: object
additionalProperties:
type: string
explode: true
- name: words
in: query
schema:
type: array
items:
type: string
这会转换为以下 URI 模板
{?formulas*,words}
当使用前面给出的数据进行扩展时,我们得到
?a=x%2By&b=x%2Fy&c=x%5Ey&words=math,is,fun
使用非 RFC6570 支持的选项进行扩展
但是现在假设(出于某种原因),我们真的希望 b
公式中的 /
在查询字符串中按原样显示,并且我们希望我们的单词像书面短语一样用空格分隔。为此,我们将 allowReserved: true
添加到 formulas
,并将 words
的 style
更改为 spaceDelimited
parameters:
- name: formulas
in: query
schema:
type: object
additionalProperties:
type: string
explode: true
allowReserved: true
- name: words
in: query
style: spaceDelimited
explode: false
schema:
type: array
items:
type: string
我们不能组合 ?
和 +
RFC6570 前缀,而且没有办法使用 RFC6570 将 ,
分隔符替换为空格字符。因此,我们需要重构数据以适应手动构建的 URI 模板,该模板将所有部分通过正确的扩展类型传递。
这是一个这样的模板,它使用一个虚构的约定,words.0
表示 words 值中的第一个条目,words.1
表示第二个,words.2
表示第三个
?a={+a}&b={+b}&c={+c}&words={words.0} {words.1} {words.2}
RFC6570 提到 使用 .
“来指示子结构中的名称层次结构”,但没有为其定义任何特定的命名约定或行为。由于 .
的使用不是自动的,因此我们需要为此新模板构建合适的输入结构。
我们还需要预处理 formulas
的值,因为虽然 /
和大多数其他保留字符在 RFC3986 中允许在查询字符串中使用,但 [
、]
和 #
不允许,并且 &
、=
和 +
在 application/x-www-form-urlencoded
格式中都具有特殊行为,这是我们在查询字符串中使用的格式。
设置 allowReserved: true
不会 使 URI 中不允许的保留字符变为允许,它只是允许它们在扩展中保持不变地传递。因此,任何工具仍然需要对这些字符进行百分比编码,因为保留扩展不会这样做,但它会保持百分比编码的三元组不变。另请参见附录 E,其中提供了有关百分比编码和表单媒体类型的进一步指导,包括有关处理参数名称和值中 spaceDelimited
、pipeDelimited
和 deepObject
的分隔符字符的指导。
因此,这是我们的数据结构,它安排名称和值以适合上面的模板,其中 formulas
的值已预先百分比编码 []#&=+
(尽管此示例中仅出现 +
)
a: x%2By
b: x/y
c: x^y
words.0: math
words.1: is
words.2: fun
使用我们重构的数据扩展我们手动组装的模板会产生以下查询字符串
?a=x%2By&b=x/y&c=x%5Ey&words=math%20is%20fun
/
和预先百分比编码的 %2B
已保持不变,但不允许的 ^
字符(在值内部)和空格字符(在模板中但在扩展变量之外)已进行百分比编码。
未定义的值和手动 URI 模板构造
在手动构造模板以正确处理 RFC6570 认为未定义的值时,必须小心
formulas: {}
words:
- hello
- world
将此数据与我们原始的 RFC6570 友好的 URI 模板 {?formulas*,words}
一起使用,会产生以下结果
?words=hello,world
这意味着手动构造的 URI 模板和重构的数据需要完全省略 formulas
对象,以便 words
参数成为查询字符串中的第一个也是唯一一个参数。
重构的数据
words.0: hello
words.1: world
手动构造的 URI 模板
?words={words.0} {words.1}
结果
?words=hello%20world
作为参数名称的非法变量名称
在此示例中,心形表情符号在 URI 模板名称(或 URI)中不合法
parameters:
- name: ❤️
in: query
schema:
type: string
我们不能仅仅将 ❤️: "love!"
传递给 RFC6570 实现。相反,我们必须在数据和 URI 模板中预先百分比编码该名称(这是一个六字节的 UTF-8 序列)
"%E2%9D%A4%EF%B8%8F": love!
{?%E2%9D%A4%EF%B8%8F}
这将扩展到结果
?%E2%9D%A4%EF%B8%8F=love%21
附录 D:序列化标头和 Cookie
RFC6570 的百分比编码行为并不总是适用于 in: "header"
和 in: "cookie"
参数。在许多情况下,使用具有 text/plain
等媒体类型的 content
,并要求应用程序组装正确的字符串更为合适。
对于使用 RFC8941 结构化字段语法的 RFC6265 cookie 和 HTTP 标头,非 ASCII 内容使用 base64 编码 (contentEncoding: "base64"
) 处理。请注意,标准的 base64 编码字母表包含非 URL 安全的字符,这些字符由 RFC6570 扩展进行百分比编码;不建议通过两种编码序列化值。虽然 contentEncoding
也支持 URL 安全的 base64url
编码,但标头和 cookie RFC 没有提及这种编码。
大多数 HTTP 标头都早于结构化字段语法,对其语法和编码规则进行全面评估超出了本规范的范围。虽然 RFC8187 建议对 HTTP(标头或尾部)字段参数进行百分比编码,但这些参数出现在 ;
字符之后。使用 style: "simple"
,该分隔符本身将被百分比编码,从而违反了一般的 HTTP 字段语法。
使用 style: "form"
和 in: "cookie"
对于单个值是模糊的,对于多个值是不正确的。无论多个值是使用 explode: true
的结果还是不是,都是如此。
此样式被指定为等效于包含 ?
字符的 RFC6570 表单扩展(有关更多详细信息,请参见附录 C),这不是 cookie 语法的一部分。但是,本规范过去版本中的此样式示例不包含 ?
前缀,这表明比较并不准确。由于依赖 RFC6570 实现的实现和基于样式示例执行自定义序列化的实现将产生不同的结果,因此哪个结果正确由具体实现定义。
对于多个值,style: "form"
始终是不正确的,因为 cookie 中的 name=value 对由 ;
(分号后跟一个空格字符)而不是 &
分隔。
注意:在本节中,application/x-www-form-urlencoded
和 multipart/form-data
媒体类型分别缩写为 form-urlencoded
和 form-data
,以提高可读性。
百分比编码用于 URI 和从 URI 派生其语法的媒体类型。此过程涉及三组字符,其名称在规范之间有所不同,但为了本节的目的定义如下
- 未保留字符不需要进行百分比编码;虽然对它们进行百分比编码是安全的,但这样做会产生一个未规范化的 URI
- 保留字符在 URI 语法中具有特殊行为(例如,分隔组件),或为需要定义特殊行为的其他规范保留(例如,
form-urlencoded
定义 =
、&
和 +
的特殊行为)
- 不安全字符在某些环境中解析 URI 时已知会导致问题
除非另有说明,本节使用 RFC3986 对保留和未保留的定义,并将不安全集定义为未包含在这些集合中的所有字符。
每个 URI 组件(例如查询字符串)都认为某些保留字符是不安全的,要么是因为它们充当组件之间的分隔符(例如 #
),要么(在 [
和 ]
的情况下)在历史上被认为是全局不安全的,但后来被赋予了有限用途的保留状态。
在组件内没有定义特殊含义的保留字符可以不进行百分比编码。但是,其他规范可以定义特殊含义,要求在附加特殊含义之外对这些字符进行百分比编码。
form-urlencoded
媒体类型定义了 =
和 &
作为分隔符的特殊含义,以及 +
作为空格字符的替代(而不是其百分比编码形式 %20
)。这意味着虽然这三个字符在 RFC3986 中是查询字符串中保留但允许的字符,但它们必须在 form-urlencoded
查询字符串中进行百分比编码,除非用于其 form-urlencoded
目的;有关处理表单值中的 +
的示例,请参见附录 C。
RFC7578 建议使用基于 RFC3986 的百分号编码作为一种机制,以将基于文本的每部分头数据(如文件名)保留在 ASCII 字符集内。此建议并非较早(2015 年之前)的 form-data
规范的一部分,因此必须注意确保互操作性。
form-data
媒体类型允许在其各个部分中使用任意文本或二进制数据,因此不需要百分号编码,除非定义该部分 Content-Type
需要它,否则很可能导致互操作性问题。
URI 百分号编码和 form-urlencoded
媒体类型具有复杂的规范历史,跨越多个修订版本,并且在某些情况下,不同的标准机构对其所有权存在冲突的主张。不幸的是,这些规范各自定义了略有不同的百分号编码规则,如果 URI 或 form-urlencoded
消息体将受到严格的验证,则需要考虑这些规则。(请注意,许多 URI 解析器默认不执行验证。)
本规范规范性地引用了以下相关标准
规范 |
日期 |
OAS 用法 |
百分号编码 |
注释 |
RFC3986 |
01/2005 |
URI/URL 语法 |
[[RFC3986]] |
取代 [[RFC1738]]、[[RFC2396]] |
RFC6570 |
03/2012 |
基于样式的序列化 |
[[RFC3986]] |
不将 + 用于 form‑urlencoded |
RFC1866 |
11/1995 |
基于内容的序列化 |
[[RFC1738]] |
被 [[HTML401]] 17.13.4.1 节,[[URL]] 第 5 节 取代 |
当存在 schema
时,参数对象中使用基于样式的序列化,当至少存在 style
、explode
或 allowReserved
中的一个时,编码对象中使用基于样式的序列化。有关 RFC6570 的两种不同百分号编码方法的更多详细信息,请参阅 附录 C,其中包括涉及 +
的示例。
基于内容的序列化由 媒体类型对象定义,并在存在 content
字段时与参数对象一起使用,并且在缺少字段 style
、explode
和 allowReserved
时,基于 contentType
字段与 编码对象 一起使用。每个部分都根据媒体类型(例如 text/plain
或 application/json
)进行编码,然后必须进行百分号编码,以便在 form-urlencoded
字符串中使用。
请注意,form-data
的基于内容的序列化不期望或要求数据中进行百分号编码,仅在每部分头值中进行百分号编码。
与历史规范的互操作性
在大多数情况下,严格按照 [[RFC3986]] 生成查询字符串足以通过验证(包括 JSON Schema 的 format: "uri"
和 format: "uri-reference"
),但某些 form-urlencoded
实现仍然期望使用略微更严格的 [[RFC1738]] 规则。
由于所有符合 RFC1738 的 URI 都符合 RFC3986,因此需要确保历史互操作性的应用程序应使用 RFC1738 的规则。
与 Web 浏览器环境的互操作性
WHATWG 是一个面向 Web 浏览器的标准组织,它定义了一个“URL Living Standard”,用于在浏览器上下文中解析和序列化 URL,包括解析和序列化 form-urlencoded
数据。 WHATWG 的查询字符串百分号编码规则因查询字符串是 被视为 form-urlencoded
(其中它比 [[RFC1738]] 需要更多的百分号编码)还是 作为通用语法的一部分而不同,在通用语法中,它允许 [[RFC3986]] 禁止的字符。
需要与 Web 浏览器实现最大兼容性的实现应使用 WHATWG 的 form-urlencoded
百分号编码规则。但是,它们不应依赖 WHATWG 的不太严格的通用查询字符串规则,因为生成的 URL 将无法通过 RFC3986 验证,包括 JSON Schema 的 format: uri
和 format: uri-reference
。
百分号解码算法不关心哪些字符被或未被百分号解码,这意味着根据任何规范进行百分号编码的 URI 都将被正确解码。
类似地,所有 form-urlencoded
解码算法只是将 +
-for-space 处理添加到百分号解码算法中,并且无论使用哪种编码规范,都将正常工作。
但是,如果 +
表示空格,则必须注意使用 form-urlencoded
解码,如果 +
将自身表示为文字值,则必须使用常规百分号解码。
百分号编码和非法或保留的分隔符
[
、]
、|
和空格字符分别用作 deepObject
、pipeDelimited
和 spaceDelimited
样式的分隔符,所有这些字符都必须进行百分号编码才能符合 [[RFC3986]]。这要求用户以某种其他方式预编码参数名称和值中的字符,以便在使用这些样式之一时将其与分隔符用法区分开来。
空格字符始终是非法的,并且由所有相关标准的所有版本的实现以某种方式进行编码。虽然可以使用 form-urlencoded
的 +
约定来区分参数名称和值中的空格与编码为 %20
的 spaceDelimited
分隔符,但规范将解码定义为单次传递,因此无法区分解码结果中的不同用法。
某些环境在查询字符串中使用未编码的 [
、]
,并且可能使用 |
而没有明显的困难,并且 WHATWG 的通用查询字符串规则不要求对它们进行百分号编码。依赖于保留这些分隔符不编码,同时在名称和值内对它们使用常规百分号编码的代码,不能保证在所有实现中都可互操作。
为了实现最大的互操作性,建议在对这些样式的分隔符进行百分号编码的同时定义和记录额外的转义约定,或者完全避免这些样式。其他编码/转义的确切方法留给 API 设计者决定,并且预计在执行本规范中描述的序列化和编码之前执行,并在本规范的编码和序列化步骤反转后执行反转。这使其不受本规范管辖的过程之外。
附录 F:解析引用文档中的安全要求
此附录显示如何检索可通过 HTTP 访问的多文档 OpenAPI 描述 (OAD) 并解析引用(非入口)文档中的 安全要求对象。有关更多信息,请参阅解析隐式连接。
首先,入口文档是开始解析的地方。它将 MySecurity
安全方案定义为基于 JWT 的,并且它将路径项定义为对另一个文档中组件的引用
GET /api/description/openapi HTTP/1.1
Host: www.example.com
Accept: application/openapi+json
"components": {
"securitySchemes": {
"MySecurity": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT"
}
}
},
"paths": {
"/foo": {
"$ref": "other#/components/pathItems/Foo"
}
}
GET /api/description/openapi HTTP/1.1
Host: www.example.com
Accept: application/openapi+yaml
components:
securitySchemes:
MySecurity:
type: http
scheme: bearer
bearerFormat: JWT
paths:
/foo:
$ref: 'other#/components/pathItems/Foo'
此入口文档引用另一个文档 other
,而不使用文件扩展名。这使客户端可以灵活地在每个资源的基础上选择可接受的格式,假设这两种表示形式都可用
GET /api/description/other HTTP/1.1
Host: www.example.com
Accept: application/openapi+json
"components": {
"securitySchemes": {
"MySecurity": {
"type": "http",
"scheme": "basic"
}
},
"pathItems": {
"Foo": {
"get": {
"security": [
"MySecurity": []
]
}
}
}
}
GET /api/description/other HTTP/1.1
Host: www.example.com
Accept: application/openapi+yaml
components:
securitySchemes:
MySecurity:
type: http
scheme: basic
pathItems:
Foo:
get:
security:
- MySecurity: []
在 other
文档中,引用的路径项具有安全方案 MySecurity
的安全要求。相同的安全方案存在于原始入口文档中。如解析隐式连接中所述,MySecurity
通过 实现定义的行为进行解析。但是,在该部分中记录,建议工具从入口文档解析组件名称。与所有实现定义的行为一样,重要的是检查工具文档以确定支持哪种行为。