跳至主要内容

来自 APIDays Paris:OpenAPI 3.1 即将发布

作者: 2020 年 12 月 15 日博客

最初发布在 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 将支持在架构中使用 examples 关键字,允许使用 **示例数组**。通常,该数组只包含一个元素。原始的单一 example 关键字仍然有效,但 examples 是推荐的,如果两者都存在,则首选 examples。请注意,这个值数组与 OpenAPI 中 **另一个** 使用 examples 的情况形成对比,在 MediaType 内容对象中,examples 字段是一个带有字符串键的映射。困惑了吗?我们也是。Phil 有一篇专门关于 OpenAPI 示例的文章 解释了一切

还有一些其他东西从 JSON Schema 进入 OpenAPI 架构。首先:允许在架构中使用任意键;OpenAPI 放宽了对哪些字段可以出现在哪些地方的限制,以适应 JSON Schema 格式对象。此外,可以对对象进行 $ref,然后在它旁边放置键,这些键被认为是除了组件中定义的内容之外的额外内容。

content:
  'application/json':
    schema:
      $ref: '#/components/schemas/style'
      required:
        - hue

这些更改都不算很大,但能够在 OpenAPI 中使用 JSON Schema 对于任何想要将两者结合使用的人来说都是很棒的,因此承诺支持不断改进的 JSON Schema 真是个好消息。

Webhooks

我完全有偏见,因为是我提出了这个功能。我简直不敢相信 OpenAPI 之前没有支持这种常见的用例,而且我花了很长时间才意识到,这不是我不理解如何做某事——那件事确实超出了 OpenAPI 3.0 预期 API 描述的范围。

OpenAPI 3.0 确实支持 **回调**,因此如果用户应该进行 API 调用,提供一个 URL,并等待传入的 HTTP 请求作为结果发送到该 URL,那么这已经得到支持。这在端点异步返回数据时非常理想,或者在 API 调用“订阅”事件并提供一个 URL 来发送内容的某些情况下非常理想。

OpenAPI 3.1 进一步扩展了功能,允许使用 **webhook**,这些 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 中对 pathItem 进行 $ref。

想要抢先了解 webhook 在工具支持它后会是什么样子吗?Redoc 已经提供预览支持,如果您在 3.0 OpenAPI 文档中使用 x-webhooks!我的意思是,它看起来只是非常专业的 API 文档,但这是我们在这里需要的 🙂


关于 webhook 和回调的说明。相当多的端点可以被认为是 webhook 或回调,我已经开始收到关于使用哪一个的问题。这可能并不重要,但是如果没有回调是响应的先前 API 调用的,那么它肯定是一个 webhook。如果存在带有 URL 的先前 API 调用,那么您可能需要自行决定如何运作。例如,在 Vonage,传入消息的事件发送位置的配置是在应用程序级别进行的,您是否使用应用程序 API 进行操作——但我更愿意将传入消息 webhook 详细信息的 API 描述与发送消息 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 内部,您现在可以拥有 summary 以及 description 字段。两者都是可选的——title 仍然是必需的。
  • 在 license 对象中,如果您愿意,可以在新的 identifier 字段中使用 SPDX 代码,而不是与必需的 name 字段一起使用 url

最后,paths 不再 *需要* 为每个端点包含 responses 字段。当 OpenAPI 文档正在构建时,这很有用,因为它意味着即使您只在草绘 API 定义将包含的端点时,它仍然会验证。

进一步阅读

我将在录制发布后分享我的演讲链接(幻灯片在 notist 上,但请关注 OpenAPI 3.1 版本的当前状态,并阅读项目本身上的(更好的)变更日志以获取更多信息 https://github.com/OAI/OpenAPI-Specification/releases