【微服务架构】API版本控制最佳实践介绍

变化是不可避免的,增长是一件好事。当您的API已经超出了最初的意图和容量时,就该考虑下一个版本了。

无论下一次迭代是一个完整的版本升级还是一个功能扩展,重要的是要考虑你如何让你的开发人员知道它的优缺点。与传统的软件版本控制相比,API版本控制可能会对下游使用它的产品产生复杂的影响。

较大的版本调整通常意味着API代码库中一个重要的里程碑。它声明了API使用和实现需求的重大变化。不需要改变现有调用的特性添加是产品有机增长的一部分,不需要同样的考虑。

一旦你开始删除一些东西,或者戏剧性地改变现有的东西,就该考虑另一个版本了。通常,这些新版本会变成全新的产品。尽管它们共享一个共同的祖先,但是遗留api的新版本在实现时需要仔细考虑。

传统的API版本控制:n+1

可以保证新版本的服务更改包括:删除操作、重命名操作、移位数据类型或顺序的操作参数更改,以及数据类型的复杂结构更改。

版本增量还可以指示API使用需求的重大变化。它还可以对API提供的底层资源进行彻底的更改。在任何一种情况下,依赖于API实现核心功能的产品和平台都可能需要进行代码重构来适应。

这可能会耗费大量的时间和资源,因此对于多个涉众来说,使用一种合理且文档记录良好的URI版本控制方法是至关重要的。版本控制在团队中可能是一个有争议的话题,通常第一个问题就是是否使用它。

一个URI来统治所有的URI

一种思想是专注于一个不变的URI,只有一组消费标准。如果改变了API结构、改变了资源或修改了参数集,那么产品将使用相同的URI重新启动。这就把重构代码的责任推给了下游的开发人员。

蒂姆•伯纳斯-李(Tim Berners-Lee)的名字被这种方法的支持者提到。他经常说:“一个酷的URI是不会改变的。”这句话的本意是要说明新兴的互联网依靠网页内的超链接才能生存下去。互联网络在当时是一系列信息节点。

不过,世界已经改变了,我们使用的是一个相互连接的矩阵,它由功能强大、资源丰富的web服务组成。一旦服务变得广泛,早期的方法类似于软件版本号。但是,独立软件对下游的影响与相互依赖的web服务大不相同。

IBM在他们自己的“Web服务最佳实践”中解决了这个问题:

正确处理API版本控制一直是分布式系统开发者面临的最困难的问题之一。人们提出了各种各样的方案,从CORBA(公共对象请求代理体系结构)采用的自由放任的方法,到DCOM中使用的更严格的方案(分布式组件对象模型)。随着Web服务的出现,您可以利用一些新特性来帮助缓解问题,但残酷的事实是,版本控制还没有内置到Web服务体系结构中。”

什么是“最佳实践”已经随着时间的推移而演变,并由供应商对其自己产品的选择决定,而不一定来自任何外部管理机构。因此,当涉及到选择版本控制方法时,有各种各样的实践。

在向后兼容

另一个要考虑的问题是向后兼容性。对于许多web资源API的提供者来说,这是首要考虑的问题。维护一个资源密集型API的多个版本会严重消耗工程团队的时间和精力。它还会给迁移到更现代体系结构的服务带来长期的稳定性问题。

对许多人来说,引入一个实质上改变API的新版本实际上就是启动一个全新的服务。将其作为一个新产品,使用新的文档、服务水平协议、层访问更改等,可能会产生重大的业务影响。许多白板上都写满了数字,争论一个变化是工程选择还是商业转变。

一旦做出了引入新版本的决定,查看一下已建立的提供商,看看是否有经过测试的解决方案,这是很有帮助的。

更广的进行版本控制的例子

我们可以从已建立的web API提供商的版本控制实践中学到什么?谷歌从一开始就直截了当地肯定了编号版本化:“网络API应该使用语义版本化。“没有多少回旋余地。它们也有一个类似的平面系统。版本指示器使用v. major . min . patch形式。

Twilio在URL中使用了时间戳,而不是版本号。Salesforce选择vXX.X在URL的中间。Facebook会将版本预先添加到端点路径中。版本实际上是可选的,未指定的版本请求将被路由到最旧的可用版本。

请注意vX.X提供的粒度,vX.X通常用于开发,而不一定用于生产。首先检查文档,但是在生产代码中选择序号引用是一个好主意。

DevOps人员可能熟悉用于版本定义的UDDI和WDSL方法。HTTP解决方案要流行得多,但是有对这种方法的支持。它需要通过XML交换进行版本请求以获得正确的版本。

像微软、IBM和Oracle这样的巨石公司在他们的一些文档中都引用了这种方法。尽管,HTTP版本标识在许多部门和产品中被接受。

约会网络Badoo选择了持续的版本控制,即添加特性而端点保持不变。旧客户端可以使用旧字段,新客户端可以使用添加的字段。API请求是事务性的,发出一个特性请求调用并返回可用选项列表。特性检查可以作为一种状态请求。

API stylebook在版本控制方面还有其他一些方法可供探索。没有一套成文的规范,公司继续探索不同的选择。

带有Accept标头的版本

路径参数的一种常见替代方法是头交换。它们可以更详细地描述预期的响应,并且通常包含在HTTP请求中。使用特定于资源的头方法允许包含其他参数(如缓存、压缩和内容协商)。

API提供者通常在其响应中传达资源标准和限制,因此开发人员无论如何都需要检查header交换。除了响应代码之外,常见的报头响应还包括速率限制、特定的错误消息、基于时间的数据等等。

聪明的离群值使用MIME类型包含版本指示符。API提供者在其后端注册这些MIME类型,然后用户包括Accept头和Content-type头。IETF在RFC4627中合法化了这种方法。虽然这是可行的,但是选择这种方法的开发人员最终将不可避免地向管理类型解释他们的选择,这些管理类型会说:“但是它不能在HTML表单上工作,那么为什么要这样做呢?”

Accept: application/pre.company.app-v1+json Content-Type: application/pre.company.app-v1+json

关于实施的争论是深刻的,并将继续下去。因此,开发人员和供应商将不得不根据他们的具体需求做出选择。通常,最常见的方法是URI参数和头标准的组合。api接受带有参数的URI请求,然后返回带有适当响应代码的有效负载,以及(希望如此)响应头中的详细元数据。

工程师们会在公司的欢乐时光里,兴高采烈地大声讨论什么是合适的回应码。但是,这里有一些有用的负面反应,它们冗长到足以对下游有所帮助。

400: BAD_REQUEST: ApiVersionUnspecified: An API version is required, but was not specified
400: BAD_REQUEST: InvalidApiVersion: An API version was specified, but it is invalid
400: BAD_REQUEST: AmbiguousApiVersion: An API version was specified multiple times with different values
400, 405: BAD_REQUEST, METHOD_NOT_ALLOWED: UnsupportedApiVersion: The specified API version is not supported
301: MOVED_PERMANENTLY: movedPermanently: This request and future requests for the same operation have to be sent to the URL specified in the Location header of this response instead of to the URL to which this request was sent
410: GONE: deleted: The request failed because the resource associated with the request has been deleted
299: OK: Warning: "Deprecated API"

业务动机将指导版本选择

在某些方面,版本控制的技术方面是最容易解决的。真正的争论归结为产品需求、业务关注点和未来计划。就工程支持、后端资源和简单带宽而言,支持一个API的多个版本的需求可能非常高。

另外,要想做得好,新版本需要丰富的文档来成功地转换。由于对快速发展的公司来说,最新的文档往往没有什么优先级,因此它可能会以新旧文档的混搭而告终。糟糕的文档会导致时间和金钱上的巨大损失。

这里的主要要点是版本控制是一个多方面的对话。这不仅仅是一个技术问题。下游影响和遗留成本可能是巨大的,为了有效增长,应该对整个过程进行仔细考虑。

 

原文:https://nordicapis.com/introduction-to-api-versioning-best-practices/

本文:http://jiagoushi.pro/node/1208

讨论:请加入知识星球【首席架构师圈】或者小号【jiagoushi_pro】或者QQ群[11107777]