使用 API-First 方法构建 RestfulAPI(三)

使用 API-First 方法构建 RestfulAPI(三)
原文标题:Designing Restful APIs using an API-First Approach — Contract Test
原文链接:https://dev.to/ntakashi/designing-restful-apis-using-an-api-first-approach-contract-test-2n3a
作者:Nicolas Takashi


本系列共有三篇,阅读之前请确保你已阅读过该系列的前两篇文章:

今天我们将讨论契约测试(contract testing)如何确保 API 实现符合设计规范。

当我们谈论 API 时,其实就是谈论契约定义,因此我们必须记住,在 API 可以使用后,定义的契约必须得到 API 提供者的支持。要知道,即使在 API 可用之后,它仍在不断发展,而 API 生命周期中最大的挑战之一就是 API 的扩展。因为有时候,业务需求变化太大,以至于当前契约不满足新需求,需要进行整改。

😈 API 扩展问题

API 是契约定义,我们不能在一切正常的情况下违反契约。当新功能的出现导致契约的当前状态被破坏时,如果没处理好,你的用户会因此遇到很多麻烦。所以,为了在 API 开发期间获得快速反馈,你必须知道每次扩展时是否引入了重大更改。

🧪 应对方法

当 API 扩展后发生了重大变更时,有以下几种方法可以帮你快速获取反馈。

单元测试

针对 API 进行单元测试可以让你知道,当你的测试没有通过,那么你的契约就已经被破坏了。

这是一个非常容易上手的策略,几乎所有的应用程序都有单元测试套件,开发人员只需修复测试遇到的 bug 就可以了。

API 版本控制

为每次更新创建一个新版本的 API,并保留旧版本,直到你的客户迁移到新版本。

我们知道 API 版本控制是一种很好的方法,但如果你为每次更新都创建一个新版本的 API,毫无疑问,这种做法很快会让你的版本管理变得混乱,并且你将很难将所有这些版本都整理在一起。

契约测试

检查 API Design 中设计的内容和开发的内容之间的差异,在持续集成管道中运行,它会为我们提供快速反馈,这是一种非常灵活和有效的方法。

如何选择合适的应对方法

我们仔细留意一下前两个选项,会发现都有明显的缺点,要么是绕过流程,要么是可维护性问题。

将契约测试与其他两种方法进行比较,我们可以看到,如果不对原始 OpenAPI 文档进行更改,开发人员将无法绕过该过程,你的团队必须对此更改进行审查,如果可能的话,API 利益相关者也必须进行审查。

契约测试更容易实现自动化,并让你清楚地了解失败的原因。

🤖 使用契约测试方法

综上所述,契约测试是检测 API 构建时发生重大变化的最佳解决方案。为了帮助我们更好地开展工作,我们使用一个名为openapi-diff的工具,这是一个 npm 包,用于比较两个 OpenApi 文档并查找删除或添加的内容。

OpenAPI-diff 将更改分为两组,重大变动(Breaking Changes )和 平滑变动(Smooth Changes),看看示例:

重大变动

  • 删除路径或参数
  • 重命名路径或参数
  • 添加所需参数
  • 修改响应项

平滑变动

  • 添加路径或参数
  • 添加响应项
  • 添加或更新说明

安装openapi-diff非常简单,你只需要运行下面的命令之一:

// using npm
npm install openapi-diff
// using yarn
yarn add openapi-diff

如何测试

在我们继续下一步之前,非常重要的一步是提取你的代码生成的 swagger.json(这取决于你用来编写应用程序的平台)。

接下来我将使用一个 ASP.NET Core API。为简单起见,我不会展示如何在 ASP.NET Core 项目中设置 Swashbuckle。

ASP.NET Core 和 Swashbuckle CLI

由于你已将 Swashbuckle 配置到你的 ASP.NET Core 项目中,因此你可以安装一个名为 Dotnet 的工具Swashbuckle.AspNetCore.Cli,它是一个非常简单的工具,可以提取swagger.json使用项目的 DLL,如果你想了解更多关于此工具的信息,请查看 Github 文档

按照官方文档中的说明安装该工具后,你只需运行以下命令即可:

swagger tofile --yaml --output ./bin/swagger.yaml ./api/TodoApp.Api/bin/Debug/netcoreapp3.1/TodoApp.Api.dll v1

上面的命令将提取 swagger.json 并将其转换为 YAML 文件,该文件类似于我们在 API 设计过程中编写的 OpenAPI 文件。

OpenAPI-Diff 实战

现在我们有了设计过的 OpenAPI 文档和通过代码生成的 OpenAPI 文档,是时候比较这些文件并检查输出的信息了。运行下面的命令,让我们看看控制台输出:

openapi-diff ./bin/api.yaml ./bin/swagger.yaml

无修改文档:

有修改文档:

我只是对代码进行了一些更改,向端点添加了一个新的查询字符串参数GET /tasks,并从端点中删除了状态代码GET /tasks/{id},我们可以看到下面的输出:

如你所见,查询字符串参数中的更改并未被记录,但删除状态代码的更改被检测为破坏性更改。

现在,你只需将 OpenAPI Diff 添加到你的 API Pipeline,即可在每次有人更改 API 实现并将其推送到你的代码仓库时检测文档里的重大更改。

这种策略允许开发人员在他们的本地机器上运行相同的脚本,避免 Pipeline 损坏,并进行 fail-fast 验证。

🏁 总结

在我看来,在 API 生命周期中,如何避免产生破坏性的重大更改是最困难的任务。如果我们真的在乎 API 设计的持久性,可以多了解 API 应用领域里的一些案例,这样当出现新的需求时,可以尽量减少破坏 API 契约的必要性。

同时为了让这种带有破坏性的重大更改处于你的控制之下,契约测试策略会帮我们更快的获取反馈,让我们更好的处理客户遇到的问题。

通常每个代码都会在 Github 存储库 中更新,你可以运行它作为本文的补充。

订阅
qrcode

订阅

随时随地获取 Apifox 最新动态