开工福利|免费学 2200+ 精品线上课,企业成员人人可得! 了解详情
写点什么

与 Roy Fielding 谈论版本化、超媒体以及 REST

  • 2015-02-05
  • 本文字数:4856 字

    阅读完需:约 16 分钟

为 Web__ 设计、实现和维护 API__ 不仅仅是一项挑战;对很多公司来说,这是一项势在必行的任务。本系列 将带领读者走过一段旅程,从为API__ 确定业务用例到设计方法论,解决实现难题,并从长远的角度看待在Web__ 上维护公共API _。沿途将会有对有影响力的人物的访谈,甚至还有 API__ 及相关主题的推荐阅读清单。_

这篇 InfoQ 文章是 Web API从开始到结束系列文章中的一篇。你可以在这里进行订阅,以便能在有新文章发布时收到通知。

Roy T. Fielding 是来自于 Adobe 的一位高级首席科学家,也是全世界促进网络软件的主要推动力之一。当他还是一位即将毕业于加利福尼亚大学尔湾分校(UCI)的学生时,他在所参与的一个课堂项目中创建了一个对 Web 进行维护的机器人,名为 MOMSpider 。其间,他还抽空创建了 libwww-perl 这一类库,其中的一些底层原则也在之后成为了 WWW 的架构的一部分。当时,Fielding 为这一部分原则命名为 _HTTP__ 对象模型 _(HTTP Object Model)。若干年之后,在他进行博士毕业论文设计的时候,他将这一模型重新命名为_ 具象状态传输_,或简称REST。它为我们展现了“一个设计良好的Web 应用程序的行为的多种特征”。

Fielding 对于开放标准做出了各个方面的巨大贡献,他的名字也总是出现在各种 RFC 规格说明中,包括 HTTP URI 模板等等。Fielding 同时还是 W3C 组织定义的“不要跟踪”请求标准的编辑之一。此外,作为 Apache HTTP 服务器项目的创始人之一,他还协助创建了这一世界上最流行的 Web 服务器软件、编写了 Apache 授权协议、成立了 Apache 软件基金会,并担任了该基金会的第一任主席。

最近,Roy 正辗转于各个有关于标准的会议之间,在此期间,他抽空回答了对于某一个经常引起争论的主题的一系列问题,这一主题就是 Web 的版本化。他也解释了为什么在他所定义的 REST 风格中,超媒体是必不可少的、设计一个能够适应未来变化的网络软件的过程、以及在设计能够在几十年之后继续可用的软件时会遇到的种种挑战等等。

InfoQ**:在 2013年 8月,你在 Adobe Evolve大会上举办了一场演讲,在演讲你对于如何对 Web的 API**** 进行“版本化”提供了一个建议,总结起来就是一句话:“不要版本化。”对于这项建议,你所看到的听众的反应是怎样的?**

Roy我认为与会的每个人都对此给出了积极的回应,因为大多数与会者都是我们的客户,并且非常熟悉 Adobe Experience Manager 产品的设计理念。当然,我不仅仅是对着幻灯片 _ 照本宣科 _,而是详细地解释了这一结论背后的理论。

在讨论的幻灯片发布到互联网上之后,各种声音就更多一些,某些读者误解了我对版本化的定义,还有些读者误解了更改主机名与商标(branding)的意义。我所说的版本化,是指将客户端可见的接口数量限定在某些名称内,这样一来客户端就可以对每个操作进行标记,将这些操作归于该 API 的某一版本。

不幸的是,对接口名称进行版本化,只是从 API 作者的角度而言实现了对变更的管理。这一点是对接口设计哲学的短视行为:作者渴望对 API 进行控制,而忽略了客户对于良好的持续性的需求。

InfoQ:那么,如果你为某个 API实现了版本化,会发生什么事呢?

Roy有以下两种可能,(a) 版本最终产生了变更,所有为之前版本所设计的组件不得不重启、重新部署、甚至于被完全抛弃,因为这些组件无法适应新系统所带来的好处。(b) 版本永远不会产生变化,就像一个永远不动的吊锤一样,它导致的结果是每个 API 调用都显得低效。

许多开发者对此举手表达他们的厌恶之情,并且坚持声称我不理解他们所遇到的问题:他们的系统非常重要、他们要对系统进行变更、要加入新的特性、数据也要进行重新组织。他们需要某种方式,让旧版本的客户端能够和新版本的客户端共存。

一般来说,遇到这种问题,我总需要解释一下,为什么“超媒体即应用状态引擎”是 REST 中不可缺少的一环。它不是可选的,也不是“最好能有”的,而且必须的。换句话说,如果你放弃这一点,就等于放弃了 REST。如果客户端将 API 的可控性寄托于部署方案的设计,那你是不可能让 API 保持逐步演化的。对于 API 的可控性必须在运行过程中进行学习,这一点正是超媒体所实现的功能。

但是,仅仅通过使用超媒体还是不足以实现逐步演化的目标。超媒体允许应用程序按需提供控制行为,但我们还需要能够让客户端理解它的表现形式的能力(对媒体类型及其所预期的处理过程的理解)。这一点是按需实现代码的闪光点。

InfoQ:如此说来,超媒体作为 REST风格不可缺少的一部分的原因之一,就在于它能够随着时间的推移对变更进行处理,是这样吗?

Roy对于变更的预期是 REST 的核心思想之一。有经验的开发者考虑到了 API 在未来可能发生的各种变化,随之想到,对接口进行版本化正是应对这些变更的正确方法,这也不是不能理解。但随之而来的问题是,在何处、以及怎样对 API 进行版本化,这方面的争论永远也不会停止。

某些开发者在内部软件的管理过程中学到了一些经验,他们相信能够控制客户端及服务器的部署,这是可以理解的。但对于那些志在跨越多个组织的界限的互联网软件来说,对于客户端及服务器的部署的完全控制则是不可能的。而这正是 REST 试图解决的问题:如何在不破坏或替换已部署的组件的情况下,对系统进行无痛升级。

因此,我的幻灯片试图将人们的注意力转回正确的方向:逐步演化的能力。换句话说,不要总想着将 API 设计为 RESTful 的,而是要想着设计一套有着你所需要的各种特性的 API。REST 的作用在于它能够引导出这些对于为多个组织服务的系统具有重要意义的特性,例如演化能力。演化能力意味着系统在适应新的变更时,无需进行重启或重新部署。

InfoQ:这是不是意味着,只要我使用 REST风格,我就不会遇到版本化所带来的问题?

Roy并非如此。总是会有某些原因,会促进你设计一套完全不同的 API,尤其是当接口的语义产生变化、或是由于安全性的原因会要求你抛弃之前所部署的软件。我的观点是,不要用版本 ID 来定义一次天翻地覆的大改动,而是用主机名来处理。因为你所创建的不是一个 API 的新版本,而是一个带有新商标的新系统。

在 Web 上,这种新系统就是指一个全新的网站。网站上不会存在任何版本号,因为它们根本不需要。RESTful API 同样也不需要版本号,一个(正确设计的)RESTful API 对于客户端来说就是一个网站,只是它的受众相对有限而已。

InfoQ**:在你的讲座中,当你讲到你所定义的 REST架构风格时,你提到 REST的设计能够支持“几十后的软件工程的规模”。从实质性的角度来说,你所说的“几十年后的规模”是指什么?**

Roy我在最初创建 REST 的时候,是为了解决我当时所遇到的一个问题:如何在不破坏 Web 的情况下改善 HTTP。在 1994-95 年那段时间,我正在重新 HTTP 协议,这是我遇到的一个重要的问题。当时我还是一位软件工程方面的博士后学生,我试图不要破坏在那个年代中已成为标准的一些东西,这就意味着我必须设计出一个能够应对今后几十年中全世界的人们所进行的各种变更。想象一下,在 1994 年创建的软件系统,有多少个延用至今的?我的意思正如字面所说:让系统在几十年后依然能够发挥作用,同时保证系统在独立且正交的方向进行演化,而不需要对系统进行关机或是重新部署。目前为止,已经过了两十年了。

InfoQ:你自己也承认,这种水平的软件工程是大多数架构师、设计师和开发者无法做到的,那么为什么还要讨论这种级别的软件工程规模呢?

Roy我之所以谈到这一点,是因为人们对于使用 REST 进行机器与机器之间通信这一方式的第一反应往往是,“既然客户端知道要发送的内容,为什么还要使用超媒体呢?它只会降低交互的速度。”这套系统设计的理念是通过解耦实现演化能力,而对于那些将“让系统在下周之内运行”,或是“我们会在下次发布中解决问题”视为金科玉律的开发者来说,他们显然无法理解这一理念。

如果开发者们期望让他们的系统运行得更长久,他们就能够从“为什么要让系统随着时间推移进行变更”的偏见中跳出来。这时我们可以将时间跨度从几十年缩短到几年(在这段时间内,你的用户群已经截然不同了),甚至缩短到几个月(在这段时间内,你还能够控制客户端的部署吗?)。

InfoQ**:HTTP这一应用层的协议通常被视为一个能够适应几十年变化的软件工程的成功案例。如今,HTTP已经发布了若干版本,而较早的 HTTP版本中存在着大量的 **错误 **,例如 Host头,绝对时间的缓存指令等等问题。这一点与你对于 Web API**所建议的“不要版本化”是否存在矛盾。

Roy不,HTTP 不会对接口名称进行版本化,在接口方法或 URI 中也不存在版本号。但不意味着通迅的其它方面不存在版本化。我们需要变更,否则我们将无法随着时间推移而改进。我们所看到的变更包括描述数据的定义语言。我们只是不欢迎破坏性的变更,因此,版本化更多地用于信息的变更,而不是用于契约的变更。

随便说一句。正确的说,HTTP 的设计几乎是完全没有什么错误的,只是整个世界对它的应用(也是由 HTTP 所产生的应用)发生了变化。Host 这一头信息在 1992 年看来是个愚蠢的设计,因为没有人需要为某个 IP 地址指定多个域名,但业务上的需求促成了它的应用。而如果 Mosaic 没有为 HTML 加入内嵌图片的功能,那么持久性连接也会成为一个糟糕的主意。绝对过期时间对于镜像托管的意义要大于缓存,而且通常来说过期时间应该是几个星期,而不是几秒种之后。

InfoQ**:那么,从 HTTP以及 HTML随着时间推移而产生了变更的这一事实中,我们又能学到些什么呢?**

Roy从 HTTP 及 HTML 中,我们所学到的是必须定义协议或语言该如何随着时间推移进行变更,以及在他们接收到某种他们还不理解的变更时应当如何进行应对。HTTP 能够随着时间进行改善的原因,是因为我们需要新的语法必须能够被忽略,并且在语义进行变更时,必须要等到新的版本能够理解新的语义才接受这种变更。

InfoQ:如今的 Web开发者面对变更的压力似乎比从前更大了。我们是否遇到了新的问题,还是说某些问题如今变得更为常见了?

Roy我认为原因只是现在的开发者遇到这种问题的机会比以前更大了。现如今,要创建一个拥有大量访问者的网站已经变得十分容易,而在从前,要让某个公司在内网之外部署一台服务器通常都要花上几年时间。在多数情况下,这是种幸福的烦恼。

软件开发者总是要与短视进行搏斗的。

InfoQ**:最后一个问题了,除了“不要版本化”之外,你对 Web API的设计者、架构师和开发者还有什么建议,能够帮助他们解决 API随时间产生变更这个问题吗?**

Roy呵呵,我可没说不要随着时间进行变更,我只是说不要在 API 中使用破坏性的名称变更。

要想给出一些通用性的建议看起来是不可能的,因为我所说的东西是特定于所创建系统的环境与类型的。我依然建议使用 REST 创建 Web 应用程序,因为它保证系统能够在未来依然运行良好,并且会带来更多的 Web 访问(更多的可访问资源)。

关于受访者

Roy T. Fielding是来自于 Adobe 的一位高级首席科学家,也是全世界促进网络软件的主要推动力之一。当他还是一位即将毕业于加利福尼亚大学尔湾分校(UCI)的学生时,他在所参与的一个课堂项目中创建了一个对 Web 进行维护的机器人,名为 MOMSpider 。其间,他还抽空创建了 libwww-perl 这一类库,其中的一些底层原则也在之后成为了 WWW 的架构的一部分。当时,Fielding 为这一部分原则命名为 HTTP 对象模型(Object Model)。若干年之后,在他进行博士毕业论文设计的时候,他将这一模型重新命名为_ 具象状态传输_,或简称REST。它为我们展现了“一个设计良好的Web 应用程序的行为的多种特征”。

为Web__ 设计、实现和维护API__ 不仅仅是一项挑战;对很多公司来说,这是一项势在必行的任务。本系列 将带领读者走过一段旅程,从为API__ 确定业务用例到设计方法论,解决实现难题,并从长远的角度看待在Web__ 上维护公共API _。沿途将会有对有影响力的人物的访谈,甚至还有 API__ 及相关主题的推荐阅读清单。_

这篇 InfoQ 文章是 Web API从开始到结束系列文章中的一篇。你可以在这里进行订阅,以便能在有新文章发布时收到通知。

查看英文原文: Article: Roy Fielding on Versioning, Hypermedia, and REST

2015-02-05 02:219317
用户头像

发布了 428 篇内容, 共 181.8 次阅读, 收获喜欢 39 次。

关注

评论

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

我爸电脑上有个加密压缩包,我给用 Python 给解开了

梦想橡皮擦

9月日更

快速提升Golang编程能力:那就一起用Go做项目吧

博文视点Broadview

华为云GaussDB:发挥生态优势,培养应用型DBA

华为云开发者联盟

数据库 开源 GaussDB 云数据库 dba

明道云在工程项目行业中的应用场景

明道云

Tensorflow保存神经网络参数有妙招:Saver和Restore

华为云开发者联盟

神经网络 tensorflow 变量 Saver Restore

自动化会提高测试覆盖率,那测试覆盖率是什么?

禅道项目管理

测试 自动化测试 测试覆盖率

Java Stream 源码深入解析

Zexho

Java 源码 stream jdk8

vivo营销自动化技术解密|开篇

vivo互联网技术

Java 后端 软件架构设计 电商营销 平台搭建

纵观移动云对象存储发展历程,也少不了 Apache APISIX 的能力加持

API7.ai 技术团队

Apache api 网关 APISIX 企业案例 移动云

极客时间架构实战营作业三

jjn0703

架构实战营

Vue进阶(幺幺零):ant-design-vue

No Silver Bullet

Vue 9月日更

鲲鹏展翅|SphereEx 获华为鲲鹏技术认证

SphereEx

大数据包围你我,技术人如何走知识分享之路

华为云开发者联盟

大数据 开发者 技术人 华为云 知识分享

Android正确的保活方案,不要掉进保活需求死循环陷进

Halifax

android 大前端 kotlin 移动开发 语言 & 开发

统信软件张磊:国产操作系统如何获得大众市场的认可?

Jessie

开源 最佳实践 新基建 企业动态 文化 & 方法

研发人员如何进行有效沟通

KJ Meng

研发管理 团队协作 技术沟通 沟通艺术 软素质

对话华为云专家,摆脱无意义“内卷”

华为云开发者联盟

面试 华为云 就业 内卷

只需3步,快来用AI预测你爱的球队下一场能赢吗?

华为云开发者联盟

机器学习 AI 华为云 modelarts 球赛

必示科技加入云计算标准和开源推进委员会,助力AIOps行业标准建设

BizSeer必示科技

AIOPS 智能运维 必示科技

【Flutter 专题】48 图解 Android 原生集成 Flutter Module

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 9月日更

简化IT运维工作,就要学会使用自动化运维工具!

行云管家

运维 云服务 IT运维

Vue进阶(幺零九):npm install 遇到 -4048 错误的解决办法

No Silver Bullet

Vue 9月日更

常见的安全应用识别技术有哪些?

郑州埃文科技

酷家乐 UI 自动化测试平台实践

CPPAlien

测试框架 selenium BDD UI测试 活文档

小游戏如何应对大流量?Shopee Shake 的大促实践

Shopee技术团队

后端 高并发 游戏 电商大促 Shopee

手撸二叉树之二叉搜索树中俩个节点之和

HelloWorld杰少

9月日更

【LeetCode】下一个更大元素 IJava题解

Albert

算法 LeetCode 9月日更

数字化转型的终局:赛博朋克?社会主义?

龙归科技

数字化 软件系统 软件经济 赛博朋克

开放原子全球开发者峰会「开源治理」论坛预告(更新中)

开放原子开源基金会

安全系列之:跨域资源共享CORS

程序那些事

Java HTTP CORS 程序那些事 跨域资源共享

Java基础知识查漏补缺

IT蜗壳-Tango

9月日更

与Roy Fielding谈论版本化、超媒体以及REST_REST_Mike Amundsen_InfoQ精选文章