这篇文章最初由Sebastian Burgstaller 为 Bitmovin 博客撰写。Bitmovin 是 OpenAPI Initiative 的成员。
不要错过今年最全面的 API 活动 ASC 2019,该活动将于 10 月 15 日至 17 日在加拿大不列颠哥伦比亚省温哥华举行。 此处提供信息和注册详细信息。
与大多数技术产品一样,文档对于客户成功至关重要,对于 API 驱动型产品,这种观点更是如此,但好的文档只是故事的一部分。当然,我们提供了一个漂亮的仪表板,在那里您可以毫无疑问地启动一个 编码,但我们仍然发现,在我们系统中处理的大部分编码都是通过 API 调用启动的。即使这样,最好的 API 文档也只能带您走这么远——如果没有 API SDK,您需要自己实现所有调用,然后才能享受您第一次编码的内容。这就是 Bitmovin 团队始终为每个 API SDK 提供多种编程语言的详细文档的原因,因此任何开发人员都可以轻松地在几分钟内完成他们的第一个编码。
保持文档和 SDK 同步并非易事,尤其是在每周添加新功能的情况下。我们需要一种更好的方法来连接这些部分,我们的搜索使我们找到了 OpenAPI 3.0 规范。
简而言之:在过去的一年中,我们将现有的 API Blueprint 文档迁移到了 OpenAPI 格式。此迁移详细说明了 800 多个端点,因此需要相当大的工作量,但由于此迁移,我们不仅能够提供令人惊叹且详细的文档,还可以生成 API SDK,因此它们与我们的完整功能集保持同步。
让我们深入了解我们旅程的细节,并展示我们在这一过程中取得的其他成就。
什么是 OpenAPI?
这 OpenAPI 规范,以前称为 Swagger 规范,定义了如何以机器可读的方式描述和记录 RESTful Web 服务。对我们来说,这一点至关重要,因为我们希望为我们的客户提供美观且易于发现的文档。随着时间的推移,出现了不同的规范格式,例如 RAML 或 API Blueprint,但行业越来越趋向于 OpenAPI。2015 年, OpenAPI Initiative 成立,将 Google、Microsoft、IBM 等多家公司的努力汇集到一个伞形组织之下。这向行业发出了一个强烈的信号,表明这种文档格式正在成为事实上的标准,并且可以放心地使用。从那时起,许多公司和社区贡献了许多很棒的工具。
有关 OpenAPI 的技术背景
OpenAPI 文档是用 JSON 或 YAML 语法编写的,并被结构化为以下块
对我们来说最重要的块是 components,它包含我们用于请求和/或响应的 HTTP 主体的所有模型,以及 paths,它包含我们 API 提供的所有端点和操作的列表。可以在 此处 找到 OpenAPI 文档的一个简单示例。
那么为什么要迁移到 OpenAPI 呢?
更好的文档可以帮助工程团队轻松扩展并跟上需求量大的项目。以下是 Bitmovin 决定迁移到 OpenAPI 的一些主要原因:
1. 简化且可搜索的在线文档
凭借我们新的 API 定义,我们能够探索 OpenAPI 生态系统的面向文档的工具。这使我们找到了 swagger-ui 项目,该项目现在是我们在线 API 参考 的基础。现在,我们的文档不仅列出了我们产品的每个端点,还详细描述了它们,包括示例请求和示例响应。
我们发现,大多数技术人员更喜欢通过测试来了解新功能,这就是为什么我们 允许登录用户 直接从端点文档中发送请求。要了解它是如何工作的,只需单击“试用”按钮并填写请求详细信息——无需输入您的 API 密钥,我们已经为您配置了它。没有 Bitmovin 帐户? 立即注册免费试用 30 天。
在创建文档时,提供有意义、完整且最新的信息非常重要,但同样重要的是,所有这些信息都易于发现和访问。这就是为什么我们在 API 文档周围构建了一个强大的全文搜索功能。例如,想要找到用于为您的编码创建缩略图的端点?只需在顶部搜索栏中搜索“缩略图”,所有资源就会在眨眼之间列出。
2. 多语言 SDK 代码生成
为了使我们的客户能够尽可能轻松愉快地使用我们的产品,我们提供七种不同语言的 API SDK:Java、JavaScript、Python、Go、PHP、Ruby 和 C#。这些 SDK 受到积极支持,但始终是我们的挑战,即跟上产品开发的速度。添加的每个新功能都意味着它也必须在这些 SDK 代码库中实现。由于这是一个耗时(且容易出错)的过程,我们决定探索 SDK 代码生成的可能性。
这 OpenAPI 生成器 是一个用 Java 编写的开源项目,可以为多种不同语言生成 API SDK。这通过结合特定于语言的代码和一些 Mustache 模板来完成。生成器代码定义了哪种关键字在特定语言中是保留的,或者定义了变量和方法的大小写。模板基本上是带有占位符的代码片段,这些代码片段与我们的 API 定义结合在一起,将形成与 API 通信所需的 API SDK 代码。
我们评估了现有的生成器,发现它非常适合中小型 API,但对于我们的用例来说,它最终还是太有限了。让我们来看一个例子:要获取在 API 中创建的特定 AWS S3 输入的详细信息,需要调用此端点
GET https://api.bitmovin.com/v1/encoding/inputs/s3/{input_id}
使用默认生成器生成 Java SDK 后,我们将能够以以下方式调用此端点
S3Input s3Input = client.getEncodingInputsS3ByInputId(inputId);
正如您所看到的,该方法作为客户端对象的一部分生成。实际上,这个单一的客户端对象将包含我们所有的 API 方法——我们的 整个 API 表面。
我们理念的一个关键方面是,我们的客户需要能够配置编码作业的每个细节。我们提供的这种权力和自由自然会导致更大的 API 表面。与其将所有这些方法放在一个 API 客户端对象中,我们希望我们的 SDK 的结构尽可能类似于我们的 API。它们应该易于浏览,并清楚地了解何时会调用哪个端点
S3Input s3Input = client.encoding.inputs.s3.get(inputId);
因此,我们决定在生成器项目之上编写我们自己的生成器逻辑和模板。 每个端点 URL 的斜杠 (/) 也是我们 SDK 中的分割符,这意味着每个资源的方法都在其自己的小型子 API 客户端对象中生成。 这确保了我们的 SDK 用户不会被他们在任何给定时间需要选择的众多方法所淹没。 它使我们对使用我们 API 的探索方法成为可能。
当我们开始编写我们自己的生成器代码和模板时,我们估计这将是一个相对简单的任务——毕竟,我们只是想重新组织已经生成的代码。 但是,事实证明,生成器的当前设计并不鼓励我们计划中的扩展方式。 我们仍然设法使用生成器项目作为基础,我们很高兴拥有它,但我们必须投入比预期更多的时间。 在完成所有这些工作之后,我们认为像 JavaScript 这样的动态类型语言可能更适合 API SDK 生成器,因为它提供了自然的自定义可能性。 我们可能低估的另一个问题是为其各自语言设计尽可能惯用的 API SDK 所需的工作量。 使用 SDK 应该对我们的客户来说很有趣,并且感觉很自然,但同时代码需要具有前瞻性,鼓励添加而不会产生重大变化。
3. 持续集成和交付
现在我们能够生成 API SDK,下一步是自动化这个过程。 我们现在已经到了可以在我们的文档中对新的 API 端点进行原型设计,并可以在几分钟内获得一个自动生成和测试的 SDK 的程度。 在此过程中,文档也会自动进行健全性检查,并执行一系列语义验证。
为了确保每个 SDK 版本都完全正常运行,我们创建了一套数十个存根 HTTP 调用,每个 SDK 都必须在集成测试中发出并验证这些调用。 如果 SDK 没有执行套件中的请求或未能正确处理响应,我们将立即停止交付过程并提醒我们的工程师出现问题。 我们使用 Wiremock 作为模拟服务器,因为它被证明是集成到我们自动化构建过程中的完美工具。
采用 OpenAPI 对工程团队的影响
在 Bitmovin,关于新端点设计的讨论现在集中在文档上 *或* 生成的代码上。 我们甚至可以编写——尚未实现但可以编译——示例工作流程,以展示新功能如何在其他功能的上下文中使用。 一旦我们对文档感到满意,我们就可以开始在我们的后端服务中实现必要的更改。 最后,我们通过编写端到端测试来试用我们生成的 SDK,这些测试在每天晚上开始(大量)真正的编码。 所有这些步骤确保了在后端服务中正确实现所有内容,并与我们在 API 文档中定义的内容相匹配,这是一种我们以前从未在仅使用旧 API 文档时拥有的安全性。
Bitmovin 的 OpenAPI 之旅的下一步
我们已经向公众发布了 7 个计划中的 API SDK 中的 5 个。 第一个(Java)作为稳定版本发布,从现在起不会出现任何重大更改。 其他 SDK 将在不久的将来发布,我们很乐意接受您的想法和建议,以便我们提供最好的 SDK。 每个 SDK 都将发布一组示例,这样您就可以快速了解如何使用新的 SDK。
我们非常高兴我们为我们的 API 文档切换到 OpenAPI,因为这将在未来为我们节省大量时间,现在我们可以将其投资于功能开发。 保证正确和超快速 SDK 更新、美观且可搜索的在线文档和丰富的工具以及我们尚未挖掘的更多优势,这些都为我们的客户和我们带来了巨大的质量改进。 我们渴望看到我们接下来可以用 OpenAPI 做什么。
OpenAPI 特定链接
SDK 存储库