天下没有不散的宴席,无论你的 API 现在有多棒,总有一天你会想要发布一个全新的。而且新的API会与旧的API有些不兼容,可能是换了新的地址,也可能换了新的参数,或者完全关了 API。总而言之,当前的 API 不会永远存在。

但问题是,你的 API 有客户端。如果你调整了API而没有适当地警告他们,那么他们将非常不高兴。

如何安全地关闭 API,如何让用户尽可能容易地关闭 API?

有一些正确的方法可以做到这一点,包括两个新的草案头,这两个标准化头是由令人兴奋的新 IETF“ HTTP API 构建模块”工作组标准化的,这个工作组旨在帮助完成这个过程,让我们来看看。

制定一个计划

首先: 检查问题中的 API 是否有任何客户端访问。

希望你有一些 API 指标,或者至少有一些日志记录。如果你没有,那就加一些!如果你这样做了,并且你可以确定没有人再使用这个 API 了,那么你就赢了。现在就把它关掉,删除代码,跳过这篇文章,好好睡一觉。

下一个问题,如果你不打瞌睡的话,就是问问你自己是否还有其他方法可以关闭这个 API。你关闭的所有东西都会破坏别人的代码,并且花费他们的时间来修复它。如果 API 继续工作,对你的客户生态系统和整个网络的健康都有好处。

在许多情况下,旧的 API 可以在内部进行转换,以便将请求透明地转换为对新 API 的调用,而无需维护两个完全独立的版本。这是 Stripe API 版本控制方法的一个基本部分,该方法包含所有 API 变更的转换,以确保对不兼容的旧版本的请求能够继续像以前一样工作,根据需要自动转换请求和响应以使用新的代码。

像这样的转换并不总是可行的,而且永远这样做会带来显著的额外复杂性,但是如果你能做到这一点,这可以为你的用户提供一个有价值的稳定性,并且避免了大量的废弃接口和旧版本维护所需的工作。

但是,如果这个服务/地址/参数在生产环境中使用,而且还不能继续支持它,那么就必须删除它。

要做到这一点,你需要一个计划。首先有三个关键问题:

  • 你希望客户怎么办? 常见的答案包括:
    • 更新到同一API的新版本,仍然支持旧的访问。
    • 改为使用其他替代的端点/参数/服务。
    • 使用不同的服务,他们只能靠自己,你不在乎。
  • 他们应该什么时候开始从这个 API 迁移? 您提出的替代方案现在是否已经准备好了?
  • 截止日期是什么时候?例如,这个 API 什么时候会完全停止工作?(如果你还没有完全确定,你可以推迟一下这个回答)。

一旦你有了一个计划,是时候告诉人们了。

沟通

首先,要告知访问者们。

给你的邮件列表发邮件,如果你有 API 规范,就更新它们(例如 OpenAPI 在操作和参数方面有一个不赞成的字段) ,并在网上的相关文档中大声强调这一点。

你应该包括上面所有的信息: 他们应该做什么,当你建议他们开始迁移,以及他们必须迁移的最后期限(如果你有的话)。

一旦你告诉了人们,就是时候告诉计算机了,这就是新的 IETF 头文件的来源。

Deprecation 头

Deprecation 头告诉客户端,请求的资源仍然可以像以前那样工作,但不再推荐使用。你可以很简单地用一个 HTTP 头声明:

1
Deprecation: true

或者,你可以提供一个日期。这个日期告诉用户什么时候开始迁移到其他地方。这可能发生在过去(如果他们应该立即开始迁移) ,也可能发生在未来(通常意味着他们应该迁移到的东西还没有准备好)。像这样:

1
Deprecation: Thu, 21 Jan 2021 23:59:59 GMT

如果您不赞成使用整个地址或服务,那么可以在每个响应中都返回这个值。如果您反对某个特定的特性,比如参数、请求方法或请求主体中的某个字段,那么您只需要在使用该特性时在请求中返回该特性。

为了向客户机提供更多信息,可以使用 Link HTTP 响应头来链接到其他地方的端点或人们可读的文档。您可以在同一个 Link 标题中包含多个这样的组合,只需用逗号分隔它们(稍后我们将看到一个完整的示例)。该规范定义了与弃用相关的4个链接:

您可以链接到人类可读的废弃描述,如下所示:

1
Link: <https://developer.example.com/deprecation>; rel="deprecation"; type="text/html"

这是告诉您的用户发生了什么以及他们应该如何处理的主要方式。您几乎总是想要使用这个!如果你还没有得到完整的细节和最终的关闭日期,那么即使是占位符说这也会有帮助。在这种情况下,不要忘了让用户订阅更新,包括邮件列表或RSS或类似内容,这样一旦计划准备就绪,他们就可以听到完整的计划。

如果希望客户端移动到API的同一端点的最新版本,请使用此命令将它们指向此处,如下所示:

1
Link: <https://api.example.com/v10/customers>; rel="latest-version"

如果您有多个可用的 API 版本,那么一次迁移一个版本通常会更好,而不是直接从现在不推荐的最旧版本迁移到最新版本。为了帮助实现这一点,您可以链接到已弃用端点的下一个版本,而不仅仅是最新版本,如下所示:

1
Link: <https://api.example.com/v2/customers>; rel="successor-version"

如果此接口没有新的等效版本,用户需要迁移到完全不同的资源,可能是一个好的替身,可以使用替代链接来指明:

1
Link: <https://api.example.com/v2/users/123/clients>; rel="alternate"

Sunset 头

一旦你知道什么时候 API 将完全关闭,你应该添加一个Sunset头。

Sunset标头告诉客户端这将何时停止工作。这是一个硬性的截止日期:API客户必须在此日期之前搬到其他地方,并且您承诺在此之前不会破坏任何东西。

您必须在这里提供日期,而且应该是在将来。如果它是过去的,那也没问题:在这一点上,你实际上是在说“这可能在任何时候关闭,你需要立即停止使用它”。它看起来是这样的:

1
Sunset: Tue, 20 Jul 2021 23:59:59 GMT

这非常简单,不仅可以用于API关闭:您可以使用它来通知将来将用于URL迁移的HTTP重定向,或者指示某些URL的有限生存期(对于本质上是临时的内容,或者出于某些资源上的数据保留策略之类的监管原因)。它只说“这个端点可能会在这个日期之后停止执行您预期的操作,做好准备”。

此规范还提供日落链接关系。此链接旨在链接到有关关闭此特定端点的计划的更多信息(如果您有弃用链接,可能与您的文档相同)或有关您的服务的常规日落策略的更多信息。如下所示:

1
Link: <http://developer.example.com/our-sunset-policy>;rel="sunset";type="text/html"

这是一个很好的地方,指出一般的日落政策是非常有用的!日落策略告诉客户端,当您关闭端点时(例如,更换件上线一年后),用户应该如何确保他们知道这一点(邮件列表、状态页面、HTTP标头等),以及他们通常应该对此采取什么措施(更新、检查文档、跟踪链接标头)。

现在添加一个对进行弃用帮助不大,但是如果您在一年前发布了一个,您的客户就已经准备好了。发布日落/弃用策略的次佳时机是现在。如果您无论如何都在编写弃用文档,那么可能值得考虑一下。

完整示例

这些部件被设计成很好地协同工作。例如,要指示某个API最近已弃用,将在6个月后关闭,请链接到文档,并提供到下一个版本的直接链接,您应该在响应中包含如下标题:

1
2
3
4
Deprecation: Thu, 21 Jan 2021 23:59:59 GMT
Sunset: Tue, 20 Jul 2021 23:59:59 GMT
Link: <https://api.example.com/v2/customers>; rel="successor-version",
    <https://developer.example.com/shutting-down-customers-v1>; rel="deprecation"

渐进式关闭

一旦一切就绪,你的期限已经过去,你就可以开始废弃了。

但这并不意味着您需要立即完全关闭 API。渐进关闭可以帮助确保任何仍在使用此 API 的客户端在它完全消失之前得到最后一次警告机会。2018年,GitHub 在删除一些加密支持时做到了这一点: 他们先是禁用了一个小时,然后重新启用了它,两周后又永久禁用了它。

还有其他诀窍:Android在2015年对不推荐使用的原生API增加了越来越多的延迟,最终等待了整整16秒,最后完全关闭了API。这些渐进式关闭为错过截止日期的客户提供了一些灵活性,并且可能会帮助那些没有注意到弃用点的客户,并在API完全关闭之前处理该问题。

收尾吧

无论采用哪种方式,一旦您尽了最大努力传达关机信息,就应该关闭路径/功能/整个服务,删除代码,最后去小憩一下。

像这样小心地进行转换和关闭,可以让您的客户尽可能清楚地知道他们如何依赖您的 API,什么时候需要采取行动,以及他们需要做什么。这些变化可能是一个大问题,而这些信息是重要的!

这些新的草案标题不仅允许我们与人类通信,还允许我们将这些信息公开给自动化系统。随着这些头文件的普及,我真的很高兴看到更多的工具在它们上面构建。通用HTTP客户端可以根据此数据自动记录有用的警告,API生成器本身可以根据API规范为您处理越来越多的警告,HTTP调试器(如HTTP Toolkit)可以在截获的实时通信中突出显示不推荐使用的端点。这是一个开始关掉东西的激动人心的时刻!

需要注意的是,这些头文件是 HTTP 规范草案。它们可能在最终定稿之前就已经改变了。也就是说,他们已经经历了几轮修订,从现在开始,他们不太可能发生戏剧性的变化,是时候开始在野外测试他们了。

不过,这确实意味着仍有时间进行反馈!如果您对此功能如何工作以及如何更好地工作有什么想法,请联系“HTTPAPI的构建块”工作组。您可以通过电子邮件将邮件列表发送到httPapi@ietf.org。