最佳实践

此页面包含一些通用的建议,它们不严格属于 规范详解 章节,因为它们不直接与 OpenAPI 规范 (OAS) 相关。

但是,它们极大地简化了创建和维护 OpenAPI 描述 (OAD),因此值得牢记。

使用设计优先方法

传统上,在创建 OAD 时存在两种主要方法:**代码优先**和**设计优先**。

  • 在代码优先方法中,**API 首先在代码中实现**,然后使用代码注释、代码注解或从头开始创建其描述。这种方法不需要开发人员学习另一种语言,因此通常被认为是最简单的方法。

  • 相反,在设计优先方法中,**API 描述首先编写**,然后代码随之而来。第一个明显的优势是代码已经有了一个可以构建的框架,并且一些工具可以自动提供样板代码。

关于这两种方法的相对优缺点,已经进行了很多激烈的辩论,但据 OpenAPI Initiative (OAI) 的观点,**设计优先**的重要性再怎么强调也不为过。

原因很简单:**可以用代码创建的 API 数量远远超过可以在 OpenAPI 中描述的 API 数量**。强调一下:**OpenAPI 无法描述所有可能的 HTTP API,它有局限性**。

因此,除非在编码 API 时完全了解并考虑这些描述限制,否则当尝试为 API 创建 OpenAPI 描述时,这些限制将最终显露出来。到那时,正确的解决方法是更改代码,使其使用可以通过 OpenAPI 描述的 API(或完全切换到设计优先方法)。

但是,有时由于过程已经很晚,人们更倾向于修改 API 描述,使其**或多或少**匹配实际的 API。不用说,这会导致**不直观且不完整的描述**,这种描述将来很难扩展。

最后,存在许多 验证工具,可以验证实现的代码是否符合 OpenAPI 描述。在持续集成过程中运行这些工具,可以放心地更改 OpenAPI 描述,因为代码行为中的偏差将立即被检测到。

**底线:**OpenAPI 为 大量自动化工具 打开了大门。请确保使用它们!

保持单一事实来源

无论你使用的是哪种设计方法(设计优先或代码优先),始终保持单一事实来源,即信息**不**应该在不同的地方重复。这实际上与编程中使用的相同概念相同,重复的代码应该移动到一个公共函数中。

否则,最终某个地方会更新而另一个地方不会更新,从而导致头痛……在最好的情况下。

例如,使用代码注解生成 OpenAPI 描述,然后将后者提交到源代码控制,而前者仍然存在于代码中,这也很常见。结果,项目新手将不知道实际上使用的是哪一个,并且会犯错误。

或者,你可以使用持续集成测试来确保两个来源保持一致。

将 OpenAPI 描述添加到源代码控制

OpenAPI 描述**不仅仅**是一个文档工件:它们是**一等源文件**,可以驱动许多自动化流程,包括样板生成、单元测试和文档渲染。

因此,OAD 应该提交到源代码控制,事实上,它们应该是第一个提交的文件之一。从那里,它们还应该参与持续集成流程。

使 OpenAPI 描述可供用户使用

美观渲染的文档对于 API 用户来说非常有用,但有时他们可能希望访问源 OAD。例如,使用工具为他们生成客户端代码,或构建某些语言的自动化绑定。

因此,让用户可以使用 OAD 对他们来说是一个额外的优势。构成 OAD 的文档甚至可以通过同一个 API 提供,以允许运行时发现。

很少需要手动编写 OpenAPI 描述

由于 OAD 是纯文本文档,并且使用易于阅读的格式(无论是 JSON 还是 YAML),API 设计师通常倾向于手动编写它们。

虽然没有什么可以阻止你这样做,而且事实上,手写 API 描述通常是最简洁和最高效的,但对于任何大型项目来说,采用这种方法都是非常不切实际的。

相反,你应该尝试其他现有的创建方法,并选择最适合你和你的团队的方法(不需要 YAML 或 JSON 知识!)。

  • **OpenAPI 编辑器**:无论是 文本编辑器 还是 GUI 编辑器,它们通常负责处理重复的任务,允许你保存可重用组件的库,并提供生成的文档的实时预览。

  • **特定领域语言**:顾名思义,DSL 是针对特定开发领域的 API 描述语言。然后使用一个工具生成 OpenAPI 描述。需要学习一门新语言,但作为回报,可以实现非常简洁的描述。

  • **代码注解**:大多数编程语言允许你*注解*代码,无论是使用特定语法还是使用通用代码注释。例如,这些注解可以用来扩展方法签名,其中包含有关 API 端点和导致它的 HTTP 方法的信息。然后,一个工具可以解析代码注解并自动生成 OAD。这种方法非常适合代码优先方法,所以在使用它时请记住页面顶部给出的第一个建议(使用设计优先方法)…

  • **所有上述方法的混合**:完全可以用编辑器或 DSL 创建 OpenAPI 描述的大部分内容,然后手动调整结果文件。请注意上面的第二个建议(保持单一事实来源):一旦你修改了文件,**它就成为事实来源**,之前的文件应该被丢弃(可能将其作为备份保留,但不要让项目新手看到或接触到它)。

描述大型 API

这是一些与处理大型 OAD 相关的小提示。

  • **不要重复自己**(DRY 原则)。如果同一个 YAML 或 JSON 片段在文档中出现多次,那么是时候将其移到 components 部分,并使用 $ref 从其他地方引用它(参见 重用描述。这样不仅会导致结果文档更小,而且也更容易维护)。

    组件可以从其他文档中引用,因此你甚至可以在不同的 API 描述之间重用它们!

  • **将描述拆分成多个文档**:较小的文件更容易导航,但太多文件同样令人费解。关键在于找到一个平衡点。

    一个经验法则是在 URL 中存在的自然层次结构的基础上构建目录结构。例如,将所有以 /users 开头的路由(如 /users/users/{id})放在同一个文件中(将其视为一个“子 API”)。

    请记住,某些工具可能无法处理大型文件,而某些其他工具可能无法很好地处理太多文件。解决方案必须考虑你的工具包。

  • **使用标签来保持组织**:标签 在规范章节中没有描述,但它们可以帮助你排列你的操作并更快地找到它们。标签仅仅是你可以附加到 操作 的元数据(一个唯一的名称和一个可选的描述)。然后,工具,特别是 GUI 编辑器,可以根据标签对所有 API 操作进行排序,以帮助你保持它们的组织。

关于如何更有效地组织 API,有很多文献。请务必查看其他人是如何解决你现在遇到的相同问题的!

例如

  • API 风格手册 包含一些知名公司和政府机构与社区分享的内部 API 设计指南。