API版本控制的生命周期方法 - nordicapis


“成功的软件总是会改变。” -弗雷德里克·P·布鲁克斯
对于一般软件而言,同样适用于 API:成功的 API 会发生变化。原因很简单:成功的 API 被各​​种 API 消费者使用,他们需要新功能、扩展、错误修复和优化。从这个角度来看,API 的变化是不可避免的。
但这只是故事的一半。各种消费者使用 API 并依靠它们来保持稳定。否则,它会破坏他们现有的集成。他们的软件客户端依赖于 API,即使 API 中的一个小改动也足以破坏这些客户端。从这个角度来看,API 的变化是不可取的。
显然,有一个两难选择。解决这个困境是 API 提供者的任务。在这篇文章中,我想给你一些处理它的技巧。
 
版本控制的生命周期方法
为了有效地处理变更和版本控制,我们需要采用生命周期方法:研究 API 及其从开始和设计一直到退役的处理变化的能力。我希望这不会让你感到意外——应对变化也需要做好准备。这意味着在具体的变更提案出现之前考虑 API 变更方式。
我们可以将 API 的生命周期分为两个主要阶段:发布 API 之前的设计阶段和发布 API 之后的阶段。
在这两个阶段,您必须以非常不同的方式处理变化。事实上,当从一个阶段过渡到下一个阶段时,你对改变的心态需要转换 180 度。

  • 发布 API 之前

当您最初设计 API 时,您甚至可能不会考虑未来的更改。但他们会来的。因此,这里有关于如何在设计时支持 API 的演变和版本控制的三个技巧。
  • 发布 API 之前:欢迎在迭代 API 设计中提供反馈

在 API 发布之前,改变是伟大的——你应该欢迎它并寻找它。使用迭代开发方法,从测试版客户那里获得反馈,并根据您收到的 API 模拟和 API 测试版的反馈调整 API 规范。这种迭代开发应该确保您创建的 API 实际上是相对稳定的。它还应该减少近期发生变化的可能性。但是不要在这里停留在您的 API 设计上,而是立即发布 API。
  • 发布 API 之前:为版本控制准备 API 设计模式

从一开始就为版本控制创建 API 设计模式。在最初的设计时,这似乎是多余的,但它允许您在未来推出一致的版本,并为 API 使用者设定正确的期望。理想情况下,为您的 API 选择的版本控制 API 设计模式记录在您的 API 设计风格指南中。
虽然最常见的模式将 API 版本控制作为 URI 路径参数来实现,但有多种替代 API 设计模式可以使主要版本可访问:
  1. Accept 标头中的 API 版本控制:客户端可以使用 HTTP Accept 标头明确指示 API 的版本。Accept 标头仍然像往常一样包含 MIME 类型,但另外附加了版本。API 的 URI 不包含任何版本信息。对于新版本,URL 不会更改,但请求标头会更改。
  2. API 版本控制作为 URI 路径参数:最常见的版本控制技术使用带有版本号的 URI 参数。
  3. 自定义 HTTP 标头中的 API 版本控制:可以为版本定义自定义 HTTP 标头。
  4. API 版本控制作为查询参数:可以为版本定义查询参数。
  5. API 版本控制作为新的子域:可以为新版本定义一个子域。

  • 发布 API 之前:预测未来的变化

预测您的 API 未来的变化,并在您的 API 设计中适应它。每个人都知道这很困难,因为没有关于未来的确凿事实。但它是为 API 的演变和版本控制所做的必要准备。根据经验和领域知识进行评估。也许您知道您的领域中有一个即将到来的行业标准需要支持。也许您知道某些标量数据字段将来可能需要变成数组。重点是准备 API 规范,以便在不破坏更改的情况下可以朝着预期的方向发展。
 
发布 API 后
API 发布后,为了您现有 API 使用者的利益,您对 API 变化的态度需要更加保守。需要更严格地管理变革。基本规则是 API 的外部可观察行为(从客户端的角度)一旦发布就不能更改。当然,规则的例外是创建 API 的新版本。
  • 管理变革:第 0 步——变革真的有必要吗?

首先,评估提议的更改是否真的有必要。如果您可以避免更改:太好了。少一个问题。
  • 管理变更:第 1 步 – 变更是否向后兼容?

如果确实需要更改,请确定更改对 API 合同(通常是您的 Open API 规范)以及依赖 API 合同的 API 使用者意味着什么。理想情况下,您拥有已发布 API 的 API 规范和包含所有建议更改的新 API 规范。评估每个更改并确定它们是向后兼容还是不兼容。
向后兼容的变化:
  1. 添加查询参数(它们应该始终是可选的)。
  2. 添加标题或表单参数,只要它们是可选的。
  3. 在 JSON 或 XML 数据结构中添加新字段,只要它们是可选的。
  4. 添加端点,例如新的 REST 资源。
  5. 向现有端点添加操作,例如,在使用 SOAP 时。
  6. 向请求接口添加可选字段。
  7. 将现有 API 中的必填字段更改为可选字段。

不兼容的更改(又名破坏性更改):
  1. 移除或更改数据结构,即更改、移除或重新定义数据结构中的字段。
  2. 从请求或响应中删除字段(而不是使其可选)。
  3. 将正文或参数中以前可选的请求字段更改为必填字段。
  4. 将正文或参数中先前需要的响应字段更改为可选字段。
  5. 更改 API 的 URI,例如主机名、端口或路径。
  6. 更改请求或响应字段之间的结构或关系,例如,使现有字段成为某个其他字段的子项。
  7. 向数据结构添加新的必填字段。

  • 管理变更:第 2 步——处理向后兼容的变更

如果您没有发现不兼容的更改,只有向后兼容的更改,那么您应该能够在不破坏客户端的情况下实现它们。应用语义版本控制并为涵盖更改的 API 版本提供新的次要版本。这个新的次要版本将取代已经发布的 API。旧客户端不应受到更改的影响,而新客户端可以从新功能中受益。更改存在一个普遍问题,即使它们是向后兼容的。向后兼容性基于 API 规范,即 OpenAPI 规范,作为与 API 使用者的“官方合同”。但是海仑定律 告诉我们,如果有足够多的 API 使用者,就会有一个 API 使用者依赖于您的 API 的任何可观察行为,而不仅仅是 OpenAPI 规范中描述的行为。
  • 管理变更:第 3 步——处理重大变更

如果您发现至少一个不兼容的更改,它将破坏依赖已更改功能的客户端。该 API 需要一个新的主版本,并且这个新版本需要与之前的版本并行维护。此外,重要版本需要对消费者可见,并且消费者必须可以访问它们。值得庆幸的是,如果您从一开始就遵循了本指南,那么您已经拥有了一种用于选择不同版本的机制。请参阅部分(为版本控制准备 API 设计模式)。
  • 管理变革:第 4 步——日落

操作和维护多个版本的 API 需要 API 提供者方面的大量工作。迟早,旧版本的 API 必须被弃用。但这不应该是一个突然的事件,而是一个渐进的事件——就像日落一样。这就是我们称这个阶段为API 日落阶段的原因。
为 API 日落设定明确的期望,并尽早将其传达给所有受影响的 API 消费者,让他们尽可能多地处理日落并将其 API 客户端提升到新版本。您必须获取 API 使用者的联系方式,这些信息通常在他们加入时收集。在邮件列表中获取 API 使用者——不是为了营销目的,而是为了产品变化。当 API 的新版本发布时,在邮件列表中向所有 API 使用者发送有针对性的消息,包括关闭旧 API 的时间表。激励您的 API 使用者及时切换到新版本,并说明使用最新版本的好处。

结论
更改 API 的影响可能难以管理。因此,开发人员必须在 API 生命周期的早期做好准备。我们已经看到 API 版本控制在引入第一个重大更改之前就开始了——甚至在 API 最初发布之前。一个设计合理的 API 很可能能够在不破坏修改的情况下继续存在,因为它是迭代设计的,并且已经预料到未来的变化,并且定义了版本控制模式。如果这些更改最终到来,您可以将这些更改归类为向后兼容和破坏性更改。然后,对次要和主要版本做出相应的反应,并最终淘汰旧的 API 版本。