只需说不-对版本控制API

2021-02-21 11:19:12

我认为我相信我们绝不应该对我们的API进行版本化,这并不是说太多。我也知道,作为一个概念,非版本化是有争议的。有趣的是,根据我的经验,通常在方法上的分歧是由于所有人都同意的基本核心原则。也就是说,API的生产者不应通过变更破坏API的使用者。

我认为这是开始对话的良好基础。我的辩论方法是尽早在讨论中找到共识,并以此为基础。因此,让我们再次更清楚地定义该原则。

API使用者希望永远不会因他们所使用的API的变化而受到破坏。

我确信读者不会惊讶于得知我不是第一个提出无版本化想法的人。这个概念已经存在了很多年。但是,它仍然存在争议。罗伊·菲尔丁(Roy Fielding)是一位撰写论文的人,他描述了RESTFul API,并向世界介绍了HATEOAS的概念(尽管该论文从未使用过怪异的首字母缩写),这一点很准确。

Fielding在REST API的上下文中谈论此问题,如果您选择非REST态度,那该死的。在我看来,REST是一种优雅的体系结构样式,它确实使构建可演化的API变得容易,而无需屈服于版本控制。这篇文章不是详述REST的地方;那里有很多更好的资源。但是可以说使用RESTFul原理进行API设计可能是一个很好的起点。

API的生产者广泛采用了两种不破坏消费者的方法。最常见的做法(通常被认为是标准的做法)是对API进行版本控制,通常不推荐使用较旧的版本并鼓励消费者迁移。描述请求中的版本有多种方法。 URL中最可见(可能是大多数组织默认使用的一种)。其他人将通过请求中的Accept标头传递版本。您可能会遇到一些资源,这些资源表明这是最佳实践。

无论使用哪种模式,API版本控制都有缺点。一方面,支持任何一种版本都是一种痛苦。在一个版本中发现错误需要确认该错误在其他版本中不存在。如果是这样,则有两种选择。在所有版本中对其进行修复,从而按比例增加所需的测试量。或仅将其修复为最新版本,并告知消费者他们需要移动版本。而且,如果仅存在于一个地方,那么消费者应该迁移到没有错误的版本(例如最新版本),还是应该修复被取代的版本?

一些模式使版本控制的痛苦最小化。拥护者将辩称我提出的问题是可以解决的。他们是。他们已经得到解决-但是,它正在解决一个自我困扰的问题。没有版本控制可以消除这些烦恼。对于您的API使用者,他们同样受益。他们不需要更改,不受API更改的干扰,始终具有最新功能,并且需要阅读的文档很少。

让我从这篇文章的第一句话稍微回溯一下。我认为版本控制是不必要的,因为我还没有遇到需要版本控制的API设计和开发中的情况。在实践中,我尚未确信版本控制是必要的,甚至是更好的选择。以下是我建议不要使用的对话。

如果确实是“必填”字段,为什么您有不需要该API的版本?

同样,不应将其描述为必填字段或必填的新业务逻辑。如果您支持不需要的API版本,那么您就支持不需要的业务功能。充其量,这是一个可选字段,可以更改代码崩溃的路径。或者,如果确实是强制性的,为什么要支持不包含该版本的版本?

仅要求输入您自己无法解决的输入,即可使API合同尽可能简单。使API的内部功能完成复杂的工作,而不是迫使消费者去做。这样,合同可以保持简单,并且您的业务逻辑和API可以避免由于强制性更改而造成的脆弱性。

我们在字段名称中输入了拼写错误,或者我们正在更改字段的样式。如果我们更改字段名称,则会破坏使用者。

因此,请勿更改字段名称。消费者使用它很好。一位同事曾向我指出HTTP标头Referer的方向。这是错的。由于已经在使用中,因此没有建议应对此进行更正。与API字段相同。如果没有伤害,请留下。

但是,如果您确实要更改拼写,请同时支持两种拼写。也许只记录新的拼写,但如果使用旧的拼写,则不会中断。添加一个适应度函数,以指示旧拼写与新拼写的使用趋势。如果旧拼写法的使用率下降到一定水平,则可以协力将其余客户转移到其他地方,但要加倍努力,您将停止支持旧拼写法。

但是我回到我的第一个建议。不要打扰更改拼写。

这是一个有趣的话题,我通常会对其进行更深入的研究。但我首先要说明为什么需要更改结构?我敢肯定,您一定会说的,但要清楚说明为什么可以不间断地设计它。

如有必要,请考虑进行内容协商,在此情况下,消费者在Accept标头中包含他们期望的媒体类型。如果结构大不相同,则可能不是API的新版本,而是API返回的资源的新表示形式。

罗伊·菲尔丁(Roy Fielding)在有关版本控制的讨论中指出,如果API如此不同以至于您需要进行版本控制,则可能不是该API的另一个版本-也许是一个完全不同的API。

我认为Github的API做得很好。如果您将它们用作示例,那就不会错了。 Github的API版本为4。如何协调两个视图(即GitHub很好,不进行版本控制)?

我可以从重述该词开始。 13年后,Github仅使用其API的第4版。那是每3年(和一点点)的一个新版本。但仍然是一个新版本。

要注意的另一件事是,他们同时对所有API进行了版本控制。不是单独的版本控制。这是有原因的。从版本3到版本4的迁移是从REST API到GraphQL的迁移。他们没有对API进行版本控制。他们对建筑风格进行了版本化。

尽管我不了解其背后的想法,但是如果您访问Github文档主页,他们不会谈论其API的版本3和版本4,而是REST API和GraphQL API。我建议这是进一步的证据,他们认为这是建筑风格的变化。也许,现在我正在猜测,版本号是区分URL或指示他们打算旅行的方向的简便方法。无论哪种方式,我都强烈建议他们不要使用API​​版本,而应该使用架构。如果有正当理由使用版本控制,就是这样。

以上是经过清理的对话,读者可能会发现其他需要版本控制的场景,我很乐意在评论中听到。我甚至很高兴与设计人员一起工作。我不希望这看起来很简单,特别是如果您不是从扎实的API设计基础开始的话。在考虑将版本控制作为选项时,请考虑以下因素:

如果是强制性更改,为什么您支持没有这些更改的版本?

保持API合同尽可能简单。将输入要求的数量限制为使系统正常运行所必需的数量。任何业务逻辑输入都应尽可能从内部资源中检索。通过使API起作用,对合同的更改将很少见。

对API的更改会使每个消费者受益吗?如果不是,请考虑这种变化对不需要的消费者有多大影响?

您会永远支持每个版本吗?还是您将开始停用版本并迫使消费者迁移?

更改是否是由于新的业务逻辑引起的? 如果是这样,新的业务逻辑将成为每个版本的一部分吗? 如果更改是由于新的业务逻辑引起的,那您的消费者是否还要担心? 新版本是否会使API使用者的工作变得更轻松或更具有挑战性? 最终,请问自己一个问题,即版本支持的案情似乎是否如此。 “这种改变的好处是否足以证明对我们的消费者和我们而言支持多个版本的时间,精力和影响?” 您的API的成功在于使它们易于使用。 那应该包括不强迫消费者改变。 重新考虑使API使用更加困难的方法。 在设计阶段进行艰苦的工作,并希望您将拥有易于使用的,可演化的API,这些API可以维护并让所有人满意。