作者:Jeff Cousens,Civis - Analytics 高级工程师
不久前,我们决定 Civis 平台 中的所有新功能都将通过 API 端点和前端代码的组合来实现。与此同时,我们决定所有端点都将对我们的客户开放。也就是说,如果您可以通过 Civis UI 使用某项功能,您也可以利用底层 API 进行编程访问。这已经是一个巨大的力量倍增器,您可以在Civis API:扩展您的数据科学中阅读相关内容。这也意味着我们的工程团队不能仅仅为了满足 UI 的需求而破坏我们的 API 契约。
一种解决方案是依赖于 API 版本,该版本从一开始就内置于 Civis API 中。但即使有了版本,我们仍然需要知道更改是否构成破坏性更改。我们认为以下情况属于破坏性更改:
- 删除端点
- 添加新的必需请求参数
- 删除或更改请求参数或响应属性的类型
发布的指南很好,但可能会出错。我们更喜欢利用自动化解决方案来编纂我们的最佳实践,并明确和执行我们的策略。考虑到这一点,我们编写了 Swagger::Diff。Swagger::Diff 比较两个 Swagger 规范并识别任何破坏性更改。例如,要将 Swagger 项目的扩展 petstore 示例与最小 petstore 示例进行比较,验证扩展示例与最小示例向后兼容
$ gem install swagger-diff
$ wget https://raw.githubusercontent.com/swagger-api/swagger-spec/master/examples/v2.0/json/petstore-minimal.json
$ wget https://raw.githubusercontent.com/swagger-api/swagger-spec/master/examples/v2.0/json/petstore-expanded.json
$ swagger-diff petstore-minimal.json petstore-expanded.json
交换参数的顺序,它会将最小示例与扩展示例进行比较,标记最小示例中缺少的端点、参数和属性
$ swagger-diff petstore-expanded.json petstore-minimal.json
- 缺少端点
- delete /pets/{}
- get /pets/{}
- post /pets
- 不兼容的请求参数
- get /pets
- 缺少请求参数:tags (type: array)
- 缺少请求参数:limit (type: integer)
- 不兼容的响应属性
- get /pets
- 缺少默认响应
Swagger::Diff 还直接与我们的测试套件集成。人们可能会忘记运行检查,但持续集成 (CI) 不会。再加上一个返回我们当前 Swagger 规范的 API 端点,它允许我们通过 请求规范 简单轻松地比较 API 的两个版本
it 'is backwards compatible' do
production_swagger = open('https://host.domain/endpoints').read
get '/endpoints'
test_swagger = response.body
expect(test_swagger).to be_compatible_with(production_swagger)
end
每次我们推送代码时,我们的 CI 都会针对生产规范测试开发分支,如果引入了任何向后不兼容的更改,则会失败并显示详细说明向后不兼容更改的消息。这保证了不会有任何向后不兼容的更改意外地滑入我们的 API。
我们已在 BSD 3-Clause 许可下开源了 Swagger::Diff,并将 gem 发布到 RubyGems.org,并在 GitHub 上提供了源代码。我们鼓励您将其添加到您的 CLI 工具集、项目 CI 或测试套件中,并且我们欢迎问题或拉取请求。