API 版本控制的最佳实践? [英] Best practices for API versioning?

查看:43
本文介绍了API 版本控制的最佳实践?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有任何已知的 Web 服务 REST API 版本控制方法或最佳实践?

我注意到 AWS 通过端点的 URL 进行版本控制.这是唯一的方法还是有其他方法可以实现相同的目标?如果有多种方式,每种方式的优点是什么?

解决方案

这是一个很好但很棘手的问题.URI 设计的主题同时是REST API 最突出的部分,因此,它是对该 API 用户的潜在长期承诺API.

自从应用程序的演变以来,在较小程度上,它的 API 是生活中的事实,它甚至类似于编程语言等看似复杂的产品的演变,URI 设计应该具有较少的自然约束,并且应该随着时间的推移而保留.应用和 API 的生命周期越长,对应用和 API 用户的承诺就越大.

另一方面,生活中的另一个事实是,很难预见将通过 API 消耗的所有资源及其方面.幸运的是,没有必要设计将在 Apocalypse 之前使用的整个 API.正确定义所有资源端点和每个资源和资源实例的寻址方案就足够了.

随着时间的推移,您可能需要为每个特定资源添加新资源和新属性,但是一旦资源寻址方案公开并最终确定,API 用户访问特定资源所遵循的方法不应改变.

此方法适用于早期 API 版本支持的 HTTP 动词语义(例如 PUT 应始终更新/替换)和 HTTP 状态代码(它们应继续工作,以便在没有人工干预的情况下工作的 API 客户端应该能够继续这样工作).

此外,由于将 API 版本嵌入到 URI 中会破坏 超媒体作为应用程序状态的引擎(在 Roy T. Fieldings 博士论文中陈述),通过具有会随时间变化的资源地址/URI,我得出的结论是 API 版本不应该长期保存在资源 URI 中意味着API 用户可以依赖的资源 URI 应该是永久链接.

当然,可以在基本 URI 中嵌入 API 版本,但仅用于合理且受限制的用途,例如调试与新 API 版本配合使用的 API 客户端.此类版本化 API 应该是有时间限制的,并且仅供有限的 API 用户组使用(例如在封闭测试期间).否则,你就会在不应该的地方投入.

关于维护有到期日期的 API 版本的一些想法.通常用于实现 Web 服务的所有编程平台/语言(Java、.NET、PHP、Perl、Rails 等)都允许将 Web 服务端点轻松绑定到基本 URI.通过这种方式,可以轻松收集和保存文件/类/方法的集合在不同的 API 版本之间分离.

从 API 用户的 POV 来看,如果这很明显,但仅限于有限的时间,即在开发期间,使用和绑定到特定 API 版本也更容易.

从 API 维护者的 POV 来看,通过使用主要处理文件作为(源代码)版本控制的最小单位的源代码控制系统,可以更轻松地并行维护不同的 API 版本.

然而,API 版本在 URI 中清晰可见,有一个警告:人们也可能反对这种方法,因为 API 历史在 URI 设计中变得可见/不可见 因此易于更改时间,这违背了 REST 的指导方针.我同意!

解决这个合理反对的方法是在无版本 API 基础 URI 下实现最新的 API 版本.在这种情况下,API 客户端开发人员可以选择:

  • 针对最新版本进行开发(承诺维护应用程序以保护其免受可能破坏其设计不良的 API 客户端的最终 API 更改的影响).

  • 绑定到特定版本的 API(这很明显)但仅限于有限的时间

例如,如果 API v3.0 是最新的 API 版本,则以下两个应该是别名(即对所有 API 请求的行为都相同):

<前>http://shonzilla/api/customers/1234http://shonzilla/api/v3.0/customers/1234http://shonzilla/api/v3/customers/1234

此外,如果 API 客户端使用的 API 版本已过时,则应通知仍尝试指向 API 的 API 客户端使用最新的先前 API 版本不再支持.因此,访问任何过时的 URI,如下所示:

<前>http://shonzilla/api/v2.2/customers/1234http://shonzilla/api/v2.0/customers/1234http://shonzilla/api/v2/customers/1234http://shonzilla/api/v1.1/customers/1234http://shonzilla/api/v1/customers/1234

应返回指示重定向的任何 30x HTTP 状态代码,这些代码与 Location HTTP 标头结合使用,该标头重定向到适当版本的资源 URI是这个:

<前>http://shonzilla/api/customers/1234

至少有两个重定向 HTTP 状态代码适用于 API 版本控制方案:

  • 301 永久移动 表示具有请求的 URI 的资源将永久移动到另一个 URI(它应该是不包含 API 版本信息的资源实例永久链接).此状态代码可用于指示过时/不受支持的 API 版本,通知 API 客户端版本化资源 URI 已被资源永久链接替换.

  • 302 Found 表明请求的资源暂时位于另一个位置,而请求的 URI 可能仍受支持.当无版本 URI 暂时不可用并且应该使用重定向地址重复请求(例如指向嵌入了 APi 版本的 URI)并且我们希望告诉客户端继续使用它(即永久链接).

  • 其他场景可以在重定向3xx章节中找到HTTP 1.1 规范

Are there any known how-tos or best practices for web service REST API versioning?

I have noticed that AWS does versioning by the URL of the endpoint. Is this the only way or are there other ways to accomplish the same goal? If there are multiple ways, what are the merits of each way?

解决方案

This is a good and a tricky question. The topic of URI design is at the same time the most prominent part of a REST API and, therefore, a potentially long-term commitment towards the users of that API.

Since evolution of an application and, to a lesser extent, its API is a fact of life and that it's even similar to the evolution of a seemingly complex product like a programming language, the URI design should have less natural constraints and it should be preserved over time. The longer the application's and API's lifespan, the greater the commitment to the users of the application and API.

On the other hand, another fact of life is that it is hard to foresee all the resources and their aspects that would be consumed through the API. Luckily, it is not necessary to design the entire API which will be used until Apocalypse. It is sufficient to correctly define all the resource end-points and the addressing scheme of every resource and resource instance.

Over time you may need to add new resources and new attributes to each particular resource, but the method that API users follow to access a particular resources should not change once a resource addressing scheme becomes public and therefore final.

This method applies to HTTP verb semantics (e.g. PUT should always update/replace) and HTTP status codes that are supported in earlier API versions (they should continue to work so that API clients that have worked without human intervention should be able to continue to work like that).

Furthermore, since embedding of API version into the URI would disrupt the concept of hypermedia as the engine of application state (stated in Roy T. Fieldings PhD dissertation) by having a resource address/URI that would change over time, I would conclude that API versions should not be kept in resource URIs for a long time meaning that resource URIs that API users can depend on should be permalinks.

Sure, it is possible to embed API version in base URI but only for reasonable and restricted uses like debugging a API client that works with the the new API version. Such versioned APIs should be time-limited and available to limited groups of API users (like during closed betas) only. Otherwise, you commit yourself where you shouldn't.

A couple of thoughts regarding maintenance of API versions that have expiration date on them. All programming platforms/languages commonly used to implement web services (Java, .NET, PHP, Perl, Rails, etc.) allow easy binding of web service end-point(s) to a base URI. This way it's easy to gather and keep a collection of files/classes/methods separate across different API versions.

From the API users POV, it's also easier to work with and bind to a particular API version when it's this obvious but only for limited time, i.e. during development.

From the API maintainer's POV, it's easier to maintain different API versions in parallel by using source control systems that predominantly work on files as the smallest unit of (source code) versioning.

However, with API versions clearly visible in URI there's a caveat: one might also object this approach since API history becomes visible/aparent in the URI design and therefore is prone to changes over time which goes against the guidelines of REST. I agree!

The way to go around this reasonable objection, is to implement the latest API version under versionless API base URI. In this case, API client developers can choose to either:

  • develop against the latest one (committing themselves to maintain the application protecting it from eventual API changes that might break their badly designed API client).

  • bind to a specific version of the API (which becomes apparent) but only for a limited time

For example, if API v3.0 is the latest API version, the following two should be aliases (i.e. behave identically to all API requests):

http://shonzilla/api/customers/1234
http://shonzilla/api/v3.0/customers/1234
http://shonzilla/api/v3/customers/1234

In addition, API clients that still try to point to the old API should be informed to use the latest previous API version, if the API version they're using is obsolete or not supported anymore. So accessing any of the obsolete URIs like these:

http://shonzilla/api/v2.2/customers/1234
http://shonzilla/api/v2.0/customers/1234
http://shonzilla/api/v2/customers/1234
http://shonzilla/api/v1.1/customers/1234
http://shonzilla/api/v1/customers/1234

should return any of the 30x HTTP status codes that indicate redirection that are used in conjunction with Location HTTP header that redirects to the appropriate version of resource URI which remain to be this one:

http://shonzilla/api/customers/1234

There are at least two redirection HTTP status codes that are appropriate for API versioning scenarios:

  • 301 Moved permanently indicating that the resource with a requested URI is moved permanently to another URI (which should be a resource instance permalink that does not contain API version info). This status code can be used to indicate an obsolete/unsupported API version, informing API client that a versioned resource URI been replaced by a resource permalink.

  • 302 Found indicating that the requested resource temporarily is located at another location, while requested URI may still supported. This status code may be useful when the version-less URIs are temporarily unavailable and that a request should be repeated using the redirection address (e.g. pointing to the URI with APi version embedded) and we want to tell clients to keep using it (i.e. the permalinks).

  • other scenarios can be found in Redirection 3xx chapter of HTTP 1.1 specification

这篇关于API 版本控制的最佳实践?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆