免费下载!由 O’Reilly 出版的《NGINX 完全指南》中文版已正式上线 了解详情
写点什么

怎样安全地关闭老旧的 API?

  • 2021-03-04
  • 本文字数:4099 字

    阅读完需:约 13 分钟

怎样安全地关闭老旧的API?

本文最初发表于HTTP Toolkit网站,经原作者 Tim Perry 授权由 InfoQ 中文站翻译分享。


万物都会有终结,HTTP API 也不例外。不论你的 API 今天看上去多么伟大,迟早有一天你会想发布一个全新的版本,新版本能更好地解决相同问题,在各方面可能都会有所改善,但是它因为有了新参数,与旧版本也无法兼容,或者你只是想彻底关闭旧的 API。总而言之,你现在的 API 不会永远存在。


但是,这并非轻而易举就能完成的,因为你的 API 有客户端。如果你关闭端点、参数或整个 API 而没有做出恰当的警告的话,那他们肯定会非常不爽。


那么,该怎样安全地关闭 API,让你的用户尽可能地感到轻松愉快呢?


在这方面,我们有正确的做事方式,包括两个新的头信息草案,它们正在被新的 IETF “Building Blocks for HTTP APIs”工作组进行标准化,旨在形成一个精确的过程。我们了解一下。

制定计划

初始第一步:检查相关的 API 是否真的有客户端。


希望你能有某些 API 的度量指标,至少在某些地方存有日志。如果没有的话,那把它们添加上,如果你有这些东西的话,并且你能确定没有人再使用这个 API 了,那么恭喜你,你赢了。现在,你就可以把它关掉,删掉代码,不要再管这篇文章了,好好睡一觉。


下一个问题,如果比较遗憾,你无法去睡觉的话,那就要问问自己,除了关闭这个 API,还有没有其他方案。你关闭的所有东西都有可能破坏别人的代码,并且会消耗他们的时间来修复这些问题。如果 API 能继续运行的话,对客户端的生态系统和整个 web 的健康都是有好处的。


在很多场景下,旧的 API 可以在内部进行转换,透明地转化成对新 API 的调用,这样可以避免维护两个完全独立的版本。这是Stripe的API版本管理方式的一个基本组成部分,他们在所有发生变化的 API 中都包含了转换,以确保对不兼容的旧版本 API 的请求能继续像以前那样运行,根据需要自动转换请求和响应从而可以使用较新的代码。


这样的转换并不总是可行的,而且如果永远这样做的话会带来明显的额外复杂性,但是如果你可以做到这一点的话,就能为用户提供非常有价值的稳定性,并且可以节省大量废弃旧版本或维护旧版本相关的工作。


但是,如果这个服务/端点/参数已经用到了生产环境,而且继续支持它是不现实的做法,那么它必须要被淘汰。


要实现这一点,我们就要有一个计划。我们首先要问自己三个关键的问题:


  • 你希望用户该怎么做?常见的答案包括:

  • 升级到相关功能的一个更新的、依然能得到支持的版本

  • 使用一些可替代的端点/参数/服务

  • 使用不同的服务,它们与你无关,不需要你关心

  • 用户应该何时迁离这个 API?你所提出的替代方案现在就可以用了吗?

  • 截止时间是什么时候?也就是,这个 API 何时会完全停止使用?(如果不能完全确定的话,你可以稍微延迟回答这个问题)。


计划准备就绪之后,我们就该把它告诉人们了。

沟通

首先,要把这一决定告诉人们。


发邮件到邮件列表,在 Twitter 或微博上发帖,如果有 API 规范的话,对其进行更新(比如,OpenAPI 在operationsparameters上有一个deprecated字段),并在相关的在线文档上大声强调这一点。


你应该包含上文提到的所有信息:他们应该做些什么作为替代方案,你建议他们什么时候开始迁移以及他们必须要进行迁移的最后期限(如果已经确定期限的话)。


在将这些信息告诉给人们后,接下来就该告诉计算机,而这就是新的 IETF 头信息可以发挥作用的地方。

Deprecation 头信息

Deprecation头信息能告诉客户端请求的资源现在依然像以前那样运行,但是这种方式已经不再推荐使用了。通过一个简单的 HTTP 头信息,我们就可以声明这一点:


Deprecation: true
复制代码


另外,我们还能提供一个日期。这个日期告诉用户他们何时该开始进行迁移。这个日期可以是一个过去时间(这代表他们应该立即开始迁移),也能是将来时间(通常这意味着他们要迁移到的新环境还没有准备就绪)。如下所示:


Deprecation: Thu, 21 Jan 2021 23:59:59 GMT
复制代码


如果你要废弃整个端点或服务,那么你可以在每个响应中都带上这样的头信息。如果你想要废弃的是一个具体的特性,可能是一个参数、请求方法或者请求体中的某个特定字段的话,那么你应该在该特性被使用的时候才在响应中包含这个头信息。


为了给客户端更多的信息,我们还可以使用Link HTTP 响应头信息链接至端点或人类易读的文档。在同一个Link头信息中,我们可以包含多个这样的链接,只需要使用逗号进行分割即可(后面我们会看到一个完整的例子)。该规范定义了四个与 API 废弃相关的链接:

Deprecation 链接

我们可以为 deprecation 链接指向一个人类易于阅读的描述:


Link: <https://developer.example.com/deprecation>; rel="deprecation"; type="text/html"
复制代码


这是告诉用户发生了什么以及他们该怎么办的主要方式。你应该始终使用它。如果还没有完整的详情和最终的关闭日期,那么即使只是一个占位符,这也是很有帮助的。在这种情况下,不要忘记让用户订阅更新,这可以采用邮件列表、RSS 或其他类似的方式来实现。

Latest-Version 链接

如果你希望客户端转移至 API 相同端点的最新版本,那么可以使用该链接指向它,如下所示:


Link: <https://api.example.com/v10/customers>; rel="latest-version"
复制代码

Successor-Version 链接

如果你的 API 有多个可用的版本,通常最好每次向前迁移一个版本,而不是直接从最老的、现已废弃的版本跳到最新的版本。为了帮助解决这个问题,我们链接至已废弃版本的下一个版本,而不是最新版本,如下所示:


Link: <https://api.example.com/v2/customers>; rel="successor-version"
复制代码

Alternate 链接

如果该 API 没有新的等价版本,用户最好迁移到一个完全不同的资源,它可能是一个很好的替代方案,那么我们使用 alternate 链接来指明这一点,如下所示:


Link: <https://api.example.com/v2/users/123/clients>; rel="alternate"
复制代码

Sunset 头信息

如果你知道了 API 何时完全关闭的话,那么就应该添加一个Sunset头信息


Sunset 头信息告诉客户端 API 何时会停止运行。这是一个强制的截止时间:API 客户端必须要在这个日期前进行迁移,我们承诺在这个时间前不会破坏任何事情。


在这里,我们必须要提供一个时间,它应该是一个未来的时间。不过,如果它是一个过去的时间,这也是可以的:此时就相当于说“这个 API 会在任意时刻关闭,你需要立即停止使用它”。它如下所示:


Sunset: Tue, 20 Jul 2021 23:59:59 GMT
复制代码


这非常简单,它不仅可以用到 API 关闭的场景中:我们能用它来标记将来 URL 迁移的 HTTP 重定向,或者表明特定 URL 有限的生命周期(适用于临时性的内容,或者适用于具有监管要求的特定资源,比如数据保留策略)。它所说明的就是“这个端点可能在该日期后不会再按照你的预期运行,请做好准备”。

Sunset 链接

该规范也提供了一个 Sunset 链接的关系。按照设计,它会链接至关于关闭特定端点更加详细的信息(如果你有 deprecation 链接的话,它们可能会是同一个)或者关于服务的通用 Sunset 策略。如下所示:


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


在这里我们也要指出,通用的 Sunset 策略是非常有用的!Sunset 策略会告诉客户端,当我们关闭端点的时候(比如,一年后替代方案上线),用户该如何确保他们能得知这一情况(邮件列表、状态页面、HTTP 头信息等)以及他们通常应该做些什么(更新、检查文档、遵从Link头信息)。


如果马上就要废弃某个 API 的话,添加这样的链接作用其实不大,但是如果你能在一年前就将其发布出去的话,你的客户端可能已经为此做好了准备。


除此之外,发布 Sunset/Deprecation 策略的最好时间就是现在。如果你恰好正以某种方式编写 Deprecation 文档的话,这么做是值得考虑的。

组合到一起

按照设计,这些组成部分能很好地协作。例如,为了表明某个最近废弃的 API,该 API 会在 6 个月内彻底关闭,我们要链接至文档并提供下一个版本的直接链接,那么我们应该在响应中包含如下的头信息链接:


Deprecation: Thu, 21 Jan 2021 23:59:59 GMTSunset: Tue, 20 Jul 2021 23:59:59 GMTLink: <https://api.example.com/v2/customers>; rel="successor-version",    <https://developer.example.com/shutting-down-customers-v1>; rel="deprecation"
复制代码

渐进式关闭

如果所有这些都已经准备到位,并且 sunset 截止时间已过,那么我们就可以将 API 关闭了。


但是,这并不意味着你需要立即且彻底消灭该 API。渐进式关闭能有助于确保任何使用该 API 的所有客户端都有最后的机会在它彻底消失前得到最后一次警告。GitHub 在 2018 年移除一些加密支持的时候曾经这样做:首先禁用一个小时,然后启用它,最后在两周后彻底禁用了它。


这里还有另外一个技巧:安卓在 2015 年为已废弃的原生API增加了越来越多的延迟,在彻底关闭 API 前,最终达到了 16 秒的等待。


这些渐进式的关闭为那些错过截止日期的客户端提供了一些灵活性,并且能帮助那些没有注意到废弃时间点的客户端,从而能在 API 彻底关闭之前处理一些问题。

谨慎行事

不管采用哪种方式,只要你尽了最大的努力去沟通关于 API 关闭的事情,那么现在就可以关闭端点/特性/整个服务,删除代码,然后睡个好觉。


像这样小心谨慎地进行废弃和关闭,可以让你的客户端尽可能清楚地知道他们该如何依赖你的 API,何时需要采取行动,以及他们需要做什么。这种变更可能是一件大事儿,这些信息是很重要的。


这些新的草案头信息让我们不仅可以与人类沟通,还能将这些信息暴露给自动化系统。随着这些头信息的普及,我很高兴地开始看到有更多的工具建立在它们之上。通用的 HTTP 客户端可以根据这些数据自动记录有用的警告日志,API 生成器本身也能根据 API 规范处理越来越多的问题,而 HTTP 调试器(如HTTP Toolkit)可以在截获的实时流量中为你突出显示废弃端点的使用。这是一个令人激动的时刻,我们可以开始安全地关闭 API 了!


需要注意的是,这些头信息是 HTTP 规范的草案。在最终确定前,它们有可能会发生变化。也就是说,它们经历了几轮修改,从现在开始,它们不太可能发生巨大的变化,现在能广泛测试它们了。


不过这也意味着还有时间进行反馈! 如果你对它们的工作方式和如何更好地运行有想法的话,请与“Building Blocks for HTTP APIs”工作组联系。你可以给邮件列表发邮件:httpapi@ietf.org,或者在这里查看之前的邮件列表讨论。


原文链接:


https://httptoolkit.tech/blog/how-to-turn-off-your-old-apis/

2021-03-04 15:422062
用户头像
张卫滨 业精于勤,行成于思。

发布了 481 篇内容, 共 292.7 次阅读, 收获喜欢 633 次。

关注

评论

发布
暂无评论
发现更多内容

今明两天,eBPF 技术探索和 Intel Arch 两大技术 SIG 继续开讲 | 第 57-58 期

OpenAnolis小助手

开源 ebpf intel 龙蜥大讲堂 浪潮信息

「Go框架」http请求处理流程: gin、beego等web框架是如何处理http请求的?

Go学堂

golang 开源 程序员 个人成长 12月月更

数据代码如何“产地直销”,做到持续集成持续发布?

数造万象

国产ETL 星光不问赶路人 时我不待

weigeonlyyou

oracle Prometheus Clickhouse MySQL 数据库 InfluxDB Cluster

企业金融App评测系列——微众银行以App构筑企业金融服务新生态,成为企业的随身数字银行

易观分析

企业 金融 银行

开发者可以选择哪些小游戏分发平台?

擦机鼻涕

小游戏 小游戏开发 小程序化

学习大数据开发技术能参加培训吗?

小谷哥

DAG任务调度系统 Taier 演进之道,探究DataSourceX 模块

袋鼠云数栈

开源

隐私计算之多方安全计算(MPC,Secure Multi-Party Computation)

京东科技开发者

大数据 隐私安全 多方安全 MPC OT

Docker 中的挂载卷

HoneyMoose

基于聚类算法的话术挖掘技术及在营销服场景的落地应用

中关村科金

人工智能 大数据 算法 对话机器人 技术实践

手游“Lord of Dragons Global”进军P2E市场

科技热闻

高可用软件什么意思?哪些高可用软件好用?

行云管家

高可用 双机热备 高可用软件

Java高手速成│编写你第一个数据库程序

TiAmo

JDBC 数据库· 12月月更

Code Review到底在关注些什么?

孟君的编程札记

Java CodeReview

DevSecOps 需要知道的十大 K8s 安全风险及建议

SEAL安全

k8s DevSecOps 12 月 PK 榜

物联网 IOT 设备如何脱离信息孤岛?

eng八戒

物联网 IoT 网络 网络配置 涂鸦智能

三个延伸打法,撑起华为云桌面的7年领跑

路过的憨憨

LED显示屏企业需要抓住直播的风口吗?

Dylan

LED显示屏 全彩LED显示屏 led显示屏厂家

转转AB平台的设计与实现

转转技术团队

大数据 A/B 测试

【5000字长文】从 S3 到 DataZone,亚马逊云科技用16年讲完一个数据的故事

亚马逊云科技 (Amazon Web Services)

亚马逊云科技 Builder 专栏

前端开发培训后可以从事哪些方面的工作

小谷哥

大咖说·阿里云教育|“网上浙大”数字化之路

大咖说

数字化 高校

支持API 9的Sample已上新,速来拿走

HarmonyOS开发者

HarmonyOS

大数据开发技术有好的培训机构吗

小谷哥

那些专注小程序语法编译的跨端开发平台

FinFish

前端框架 跨端开发 跨端框架 前端开发框架 前端开发平台

老板要的物联网可视化大屏,我30分钟就搞定了

华为云开发者联盟

物联网 华为云 12 月 PK 榜

无魅友,不魅族!魅族大力推广魅友文化,用行动阐述何为用户共创

Geek_2d6073

深耕数字办公,华为云桌面怎样带来高效办公体验?

路过的憨憨

【2023】合肥市等保测评有哪些公司?地址在哪里?

行云管家

等级保护 等保测评 等保2.0 合肥

怎样安全地关闭老旧的API?_安全_Tim Perry_InfoQ精选文章