REST API的语义化版本控制?

38
我已经评估了许多 REST API 的版本控制模式(header、url等)。到目前为止,最可靠的方法似乎是 url 选项:它可以与代理一起使用,而且不依赖于诸如日期版本之类的模式。
现在,当我四处寻找时,每个使用基于 url 方法的人似乎都使用诸如 v1、v2 等版本。没有人使用次要版本,甚至包括语义化版本控制这样的模式。
这引发了一些问题:
- 在什么情况下会增加 REST API 的版本号(肯定会比五年多更新一次)? - 如果只有一个错误修复,您可能不会增加版本号,但是如何区分两个版本? - 如果您使用非常细粒度的方法,您将需要并行托管大量版本。你如何处理?
换句话说,例如 GitHub 这样的公司,如何在已经经营了7年之后仅拥有v3(2015年)?这是否意味着他们只更改了两次API?我几乎无法相信。 有什么提示吗?

2
实际上,这是主要版本号。我认为资源版本控制更重要,但没有人谈论它。 - inf3rno
你可以进一步解释一下什么是“资源版本控制”吗? - Golo Roden
1
当资源发生变化时,它必须更改版本号。通过更新客户端,它必须发送本地存储的资源表示的版本号以及请求,因此服务将知道它是否具有资源的新版本。人们称之为ETag,但如果您有多个资源或响应的资源,则无法发送多个ETag标头(据我所知),因此必须在正文中发送版本号。 - inf3rno
好的,明白了,谢谢 :-) - Golo Roden
1个回答

67

对于一个web服务,您只需要主版本号。因为您的使用者只关心不兼容的更改,而且(如果您正确遵循语义版本控制),这些更改只会在发布新的主版本时引入。

所有其他更改(包括新功能、错误修复、补丁等)都应该对您的使用者来说是“安全的”。这些新功能不一定需要被您的使用者使用,而且您可能不希望继续运行包含错误X或Y的未修补版本时间太长。

在您的URL中使用完整的版本号(或您用于API版本控制的任何方法)实际上意味着每次更新/修补API时,您的使用者都必须更新API的URL,并且他们将继续使用未修补版本,直到他们这样做。

当然,这并不意味着您不能在内部使用语义版本控制!只需使用第一部分(主版本)作为API的版本号即可。在您的URL /头文件/其他版本控制系统中包含完整的版本号没有意义。

所以回答您的问题:每次发布新版本时都要更新API,但仅在有新的主版本时才发布新的API版本。这样,您只需要托管几个不同的版本(当然,您可以随着时间推移停用旧版本)。


非常感谢您详尽的回答!只有一个问题未解决:假设系统未托管在网络上,而是安装在客户端,那么我将得到许多稍微不同的给定主版本变体,对吗?我该如何处理呢?换句话说:我无法确定一个客户的 v1 是否与另一个客户的 v1 相同。 - Golo Roden
你能进一步解释一下这种情况吗?您正在开发一个API,将在许多客户服务器上运行,但仅在其本地网络上可用(因此仅在内部使用)?是这样的吗? - Nic Wortel
正确。但我们必须支持它。这意味着,客户打电话投诉REST API的问题。我们会问他们使用的版本是哪个,他们告诉我们是“v1”。不幸的是,这并没有太大帮助,因为可能有许多“v1”版本存在。当然,我们可以要求特定的服务器版本,但这是一个额外的步骤(而且我们不确定是否想要它)。这样问题清楚了吗? - Golo Roden
3
是的,我也这么认为。当然,理想的解决方案是确保所有服务器始终更新到最新版本的软件。但那可能不在你的控制范围之内。那么,在API中添加一个简单返回完整版本号的路由怎么样呢?然后您可以将人们(大多数人可能是开发人员)引导到该URL(例如http://12.34.56.789/api/v1/version)以查找确切的版本。尽管这仍需要额外的步骤,但这可能是目前最好的解决方案;) - Nic Wortel
虽然我完全同意从公共角度来看这一点,但我认为在内部(或者如果您向客户提供微服务)使用语义化版本控制API有显著的优势。如果您的组织有许多相互使用的REST API,那么在它们之间建立API依赖关系非常有用。API-A 1.0.0 首先依赖于 API-B 5.0.0,但是您对 API-A 1.1.0 的功能开发需要 API-B 5.1.0 的新的非破坏性功能。这与包版本不一定相同。 - dpwr
@dpwr 你可以两种方式暴露你的API,内部或者外部,其中主要的(/v1/)指向最新的小版本和修补程序,你也可以为需要的客户暴露明确的版本,这只是路由问题。 - robert arles

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接