最初发布在 LORNAJANE 博客 – 感谢 Lorna!
OpenAPI 3.1 中的新功能
随着 OpenAPI 3.1 即将推出,我在 APIDays Paris 上做了一个关于可以期待什么的演讲。但我非常喜欢将文字作为参考,因此这里有一个关于下一个 OpenAPI 版本中内容的文字回顾。
主要功能
– 与 JSON Schema 2020-12 兼容
– Webhook 支持
– 许多其他小改进
版本编号
从 OpenAPI 3.1 开始,OpenAPI 项目不再遵循语义版本控制。这听起来是一个完全不负责任的决定,但实际上对标准来说是有道理的,因为每个 API 描述都会明确说明其相关的 OpenAPI 版本。另外,他们不让我制定规则,很遗憾!这不是一个主要版本,但为了适应 JSON Schema,一些内容必须被撤消并重新完成。
JSON Schema 2020-12
这是一个重大的消息,OpenAPI 的很大一部分与 JSON Schema 一起使用,3.0 版本发布很久了,并没有完全适应如今 JSON Schema 中所有合理的方面。这篇文章不会涵盖 JSON Schema 本身的新内容,但我会尝试从 OpenAPI 用户的角度总结要点。
首先:类型现在可以是 **类型数组**,因此某些内容的类型可以是 [string,number]。可用类型还包括 null,因此更常见的是 [string, 'null']。这确实会影响现有的 OpenAPI 文档,因为从 3.1 开始,nullable 关键字将被删除 - 使用类型数组,其中一个类型为 null。
parameters:
- name: friendly-label
in: query
schema:
type:
- string
- 'null'
OpenAPI 3.1 正在获得对 schema 中 examples 关键字的支持,允许 **示例数组**。不过,数组通常只包含一个元素。原始的单一 example 关键字仍然有效,但 examples 是推荐的,如果两者都存在,则 examples 优先。请注意,此数组值与 OpenAPI 中 examples 的 **其他** 用法形成对比,在 MediaType 内容对象中,examples 字段是具有字符串键的映射。困惑吗?我们也是。有一篇由 Phil 撰写的关于 OpenAPI 示例的 **文章** 详细解释了所有内容!
JSON Schema 中的一些其他内容即将进入 OpenAPI schemas。首先:允许 schema 中存在任意键;OpenAPI 放宽了其对哪些字段可以出现在何处的约束,以适应 JSON Schema 格式对象。此外,可以 $ref 到一个对象,然后在其旁边放置键,这些键被视为对组件中定义的内容的补充。
content:
'application/json':
schema:
$ref: '#/components/schemas/style'
required:
- hue
所有这些更改都不算大,但能够在 OpenAPI 中使用 JSON Schema 对任何想要将两者结合使用的人来说都是很棒的,因此对支持不断改进的 JSON Schema 的承诺是好消息。
Webhook
我完全有偏见,因为我提出了这个功能。我无法相信 OpenAPI 还没有支持这种常见的用例,并且花了很长时间才意识到,这不是我不明白如何做某事 - 那个东西真的超出了 OpenAPI 3.0 对 API 描述的预期。
OpenAPI 3.0 确实支持 **回调**,因此如果用户应该进行 API 调用,提供 URL,并等待对该 URL 的传入 HTTP 请求作为结果,则该功能已经得到支持。当端点异步返回数据或在某些情况下,API 调用“订阅”事件并提供一个 URL 来发送数据时,这非常理想。
OpenAPI 3.1 更进一步,允许 **webhook**,它们是对某些外部事件或刺激做出的传入 HTTP 请求。一个很好的例子是,如果您曾经将任何内容链接到 GitHub 推送事件,或传入订单/付款/消息(我在一家通信公司工作了几年,因此您可以立即理解我如何卷入其中)。webhook 的描述与现有的回调非常相似,实际上两者都非常像现有的请求描述,因此我希望此更改能够轻松地被所有拥有类似双向 API 的人采用。
新的 webhooks 关键字是一个顶级元素,位于 paths 之旁。对必需字段也有一些更改:OpenAPI 3.0 需要 openapi、info 和 paths,但在 OpenAPI 3.1 中,只有 openapi 和 info 始终是必需的,但文档还必须包含 paths、webhooks 或 components 中的至少一个。这很棒,因为它允许 API 描述仅包含传出的 API 调用、仅包含传入的 webhook、仅包含可能被其他文档引用的组件,或所有这些的任意组合 - 并且本身仍然有效。
无论如何,回到 webhook。
webhooks:
inbound-sms:
post:
operationId: inbound-sms
requestBody:
content:
application/json: ...
responses: ...
在 webhooks 部分,每个传入的“内容”都有一个键(例如上面的 inbound-sms),然后它继续……看起来像一个 pathItem,因为它就是它。您不需要指定 webhook 将要传入的 URL 路径(通常用户可以自行指定该路径),只需解释将要到达的内容,您就完成了。哦,与此相关的是:pathItem 现在允许在 components 部分中使用,并且您可以从 path、callback 或 webhook 中 $ref 到 pathItem。
想先睹为快,看看 webhook 在工具支持它后会是什么样子吗?Redoc 已经提供了预览支持,如果您在 3.0 OpenAPI 文档中使用 x-webhooks!我的意思是,它看起来就像非常专业的 API 文档,但这就是我们在这里需要的 🙂
关于 webhook 和回调的说明。相当多的端点可以被视为 webhook 或回调,我已经开始收到关于使用哪个的问题。这可能并不重要,但如果没有回调作为响应的先前 API 调用,那么它绝对是一个 webhook。如果有先前 API 调用带有一个 URL,那么您可能需要决定您希望它如何工作。例如,在 Vonage 中,配置传入消息事件的发送位置是在应用程序级别,您是否使用 Application API 完成 - 但我宁愿在同一文档中,与发送消息 API 调用一起显示传入消息 webhook 详细信息的 API 描述,并将其标记和分组在消息 API 描述中。webhooks 关键字为您提供了灵活性,您可以按照自己的意愿来处理。
小巧但功能完善的升级
在 OpenAPI 3.1 中添加了许多小功能,但我只选择了我的最爱!与每个 *.1 版本一样,有一些事情在 *.0 版本中看起来像是一个好主意,但现在我们已经尝试过,可以稍微整理一下,这是一件好事。
我将从我想立即实施的一项功能开始(或在工具允许后尽快实施):$ref 现在可以具有 summary 和 description 作为同级元素,并且它们会覆盖所引用组件上的任何现有字段。
paths:
/items:
post:
parameters:
- $ref: '#/components/parameters/item'
description: The specific item in question
info 部分中也有一些小改动
- 在 info 中,您现在可以在 description 字段旁边添加 summary。两者都是可选的 - title 仍然是必需的。
- 在 license 对象中,如果您愿意,可以使用新的 identifier 字段中的 SPDX 代码代替 url,与必需的 name 字段一起使用。
最后,paths 不再 **需要** 为每个端点提供 responses 字段。这在 OpenAPI 文档处于构建阶段时非常有用,因为它意味着即使您仍然只是草拟 API 定义将包含的端点,它也能通过验证。
进一步阅读
当录制发布时,我会分享我的演讲链接(幻灯片在 notist 上,但请关注 OpenAPI 3.1 版本的当前状态,并在项目本身中阅读(更好的)更改日志以获取更多信息 https://github.com/OAI/OpenAPI-Specification/releases。