本文关键点

  • 在过去的几年中,软件开发社区中出现了越来越多的反REST观点。然而,替代技术经常出现在特定的上下文中,它们呈现出优点和缺点往往与特定用例相关。

  • REST崛起本身就是由一种错误的二分法导致的,当时SOAP扮演了反面角色。SOAP试图提供一种通过Web协议打通隧道的方法,而REST方法则拥抱了这种方法。

  • 软件工程行业不应该寻求替代REST,而应该在开发新协议技术优势的同时构建成熟的REST生态,从而谋求更进一步的发展。

新的API协议(如GraphQL、gRPC和Apache Kafka),作为受REST启发的HTTP API的替代品,越来越受到欢迎。本文认为在一对一协议中体现不出REST范式的优势。软件工程行业不应该寻求替代REST,而应该在开发新协议技术优势的同时构建成熟的REST生态,从而谋求更进一步的发展。

关于协议、范式和错误的二分法……

温哥华人Tim Bray最近的博客文章“后REST”引起了业界的广泛关注,这是有原因的。随着Web API得到越来越多的应用,人们开始怀疑REST1是否是Web API的理想通信约定。除了开放Web通信最初的范围之外,REST现在还用于提供Web应用程序数据、提供微服务间通信、促进基础设施管理和自动化,甚至还用于消息传递、事件分发和流等异步模式。

Tim的文章很好地概括了REST的用法、它的局限性、一些新兴的替代协议(GraphQL和gRPC),并推测了Web API通信的未来。虽然我大致上也赞同这篇文章的观点,但我觉得这个话题不应仅限于这些,还有更多内容要谈。换句话说,我不只是想看看什么可以替代REST,更希望我们考虑一下如何将REST的优势与这些新协议的创新结合起来,从而为分布式软件生态系统中的通信提供不断演进的替代方案。

新的协议,旧的战线,错误的二分法

在过去的几年中,软件开发社区中出现了越来越多的反REST观点。许多文章都指着REST的局限性大发牢骚,并提出了替代的通信协议或方法。

在支持 GraphQL、gRPC、异步通信的声音中,甚至更模糊的观点中,经常看到“REST在x上不好,所以使用y代替”的说法。这些争论差不多是这样说的:

  • GraphQL比REST更好,因为它能够让API消费者控制接收到的数据,并能让API提供者在服务器端聚合资源

  • gRPC(加上协议缓冲区)比REST更好,因为它是类型安全的,它通过二进制序列化优化了性能,并且能够利用HTTP/2的能力

  • 异步的通信(AMQP、Kafka等)优于同步的REST通信,因为它减少了阻塞和线程使用,从而提高了服务的自治

这些方法都是在特定的上下文中产生的。GraphQL是由Facebook创建的,在他们重新开发Facebook移动应用程序时,它也是其中的一部分。它是与Relay和React原生JavaScript框架一起使用的在线通信方法,本质上,这一方法是为应用程序提供特定的数据。许多GraphQL的公开支持者都倾向于数据中心和JavaScript,这一点大家都能想到。gRPC和协议缓冲区本来是谷歌内部使用的,并遵循与Kubernetes容器编制项目类似的公开路径。许多的gRPC倡导者都集中在基于容器的应用程序之间的通信上,这一点大家也都能想到。互斥异步通信通常用于响应式系统或事件源的上下文中。在这些特定的上下文中,专门为其设计的方法自然会比那些更通用的REST方法具备一些优势,这是件很自然而然的事。

为了捍卫REST,我们很容易流于表面去看待这些批评,并提出如下的观点:

  • 对于GraphQL案例,REST范式中完全没有限制用户选择或资源聚合(在单个资源上使用静态接口只是一种常见的实践),而且大量信息表明,就算限制用户选择也有其自身的好处

  • 对于gRPC,运行时优化不太可能是大多数分布式体系结构中的主要瓶颈,而gRPC的对嵌入类库的需求(更不用说protobuf的枚举结构)可能会导致无法预见的问题

  • 对于异步,绝对有必要包括基于事件的场景,但是这些场景很可能是除同步模式(如查询和命令)之外额外的

然而,在我看来,这些反面意见并不能说明一切。软件工程是一个还缺乏REST的行业,我们经常过度简化我们的问题,以证明过于简单的解决方案是合理的。我们喜欢给“当红的平台”贴上标签,以激励大家迅速跳到一些新的安全地带。因为批处理不好,所以实时处理就是好的。因为整体系统不好,所以微服务就是好的。在特定上下文中使用REST,它就变成了个反面典型,这就像上面的论调一样,其实就是非好即坏的错误的二分法。也许我们应该研究研究另一个问题:REST是如何成为用于分布式计算中组件到组件网络跳转的默认通信方法的?让我们穿越回最开始的时候。

REST的起源、兴起和流行

Roy Fielding在2000年博士论文“架构风格与基于网络的软件架构的设计”中有一章定义了REST(表述性状态转移)。本篇论文的主要目的是“定义一个理解软件架构的框架”……,以指导基于网络的应用软件的架构设计。在架构风格示例中,REST就包含其中,这些架构风格将万维网的设计原则编写成代码,重点强调了接口的可演化性、可伸缩性和通用性。与上文列出的新方法的上下文相比,REST一开始的问题领域有着非常广阔的空间。

在这广阔的空间之中,其中一个想法非常流行,那就是在浏览器之外基于网络共享数据和服务。软件开发人员快速基于Fielding的工作成果并将其付诸实践3。REST崛起本身就是由一种错误的二分法导致的,在当时SOAP扮演了反面角色。SOAP试图提供一种通过Web协议打通隧道的方法,而REST方法则拥抱了这种方法。“REST是Web的一部分,而不仅仅是在Web上”,对于已经在构建基于Web的解决方案的软件工程师来说,这一概念他们从直觉上更愿意直接去选择它。

随着SOAP和WS-*生态环境变得越来越复杂,由于REST的相对简单性和可用性,使其胜出了。随着时间的推移,JSON出于类似的原因取代了XML,成为Web API事实上的数据格式。随着Web计算范式的使用扩展到新的场景(比如企业应用程序集成、云供应、数据仓库查询、物联网等等),REST API采用的范围也随之扩展。

现在,如果针对每个特定的使用场景审视一翻,可能REST的适用性会存在一些弱点,或者会有一些看起来更理想的替代通信方法。但这么比较就忽视了REST所具备的广泛性能力。由于REST的广泛性,已经惯于使用AJAX调用的Web开发人员可以凭直觉掌握如何使用AWS的API来提供云基础设施;基于Web的社交网络的开发人员可以迅速为移动应用程序铺设管道;企业级软件的开发人员所能做到的大家就更为熟悉了,他们可以使新拆分的微服务相互通信。软件工程是这样一个领域:交付障碍往往是人为造成的,而不是机器。充分理解方法提供的价值,通常比技术最优化的利基解决方案对交付时间有更大的影响。

在REST生态系统中,这种广泛性还带来了健壮性。Swagger(现在是OpenAPI)作为元数据规范适时出现,成为一个有机的补充,它旨在帮助开发人员记录、设计和使用API。OAuth为身份验证和授权提供了一个可伸缩的、可转换的框架。“API管理”作为一组特性出现,包括速率限制、动态路由、缓存等,实践证明这些在提供REST API时非常有用。REST范式的全面性及其生态系统的成熟度表现出REST作为软件系统中基于网络的通信方法的最大价值。很可能,这种广泛性更多地来自于REST成为“Web工作的方式”,而不是任何一个技术细节。

后Web范式中的通信

Web对软件工程的影响再怎么强调都不为过。在REST兴起的同时,软件工程领域也涌现出了开源、敏捷、DevOps、领域驱动设计和微服务体系架构。这些运动中的每一个都得益于Web,它们不约而同地放大了软件交付中人为因素的重要性。随着云计算提供的灵活性和方便性,已经涌现出一种新的软件工程范式,它的特征是持续运行、持续发展、松耦合的应用程序和服务。虽然Tim Bray将他的文章称为“后-REST”,但也许这种新范式可以称为“后-Web”。由于这种范式的特征与Fielding的REST的原始原则是一致的,因此舍弃REST从头开始是没有意义的。换句话说,忽视20年来的技术创新同样是个很幼稚的做法。

那么REST的价值在这个新范式中如何演变呢?现在,越来越多的组织采用“API为上”的方法进行软件开发,也就是说,强调在应用程序和服务中机器接口的设计与UI的设计同样重要,并应借助这些API来解耦负责不同领域的团队的开发工作。OpenAPI通常在这种方法中扮演重要角色,因为它是与实现无关的接口规范。根据后-Web范式,这对构建或修改软件系统的各方面人员都有好处。目前已经有一个正在进行的项目,它是来自Fran Mendez的AsyncAPI ,其旨在为基于事件的交互带来同样的价值。沿着同样的思路,Mike Amundsen和Leonard Richardson引入了ALPS规范来记述基于网络的应用程序交互的语义。像这些成果有助于解决构建分布式系统的设计时的挑战。

在云本地运行时中也有机会扩展REST的价值。向微服务的迁移引入了进程间通信(IPC)常常发生的网络边界问题。这些物理边界可以刻意投影为业务领域边界,以实现上面讨论的人员利益。

但是,这存在一个潜在的运行时权衡,即额外的网络延迟和服务调用链中出现部分故障的可能性。

服务网格模式为基于容器的系统解决了这些问题,它的特点是有一个“边车”服务代理,由它处理应用组件之间所有基于网络的通信。服务网格拓扑意味着,已经在应用程序容器及其相关的边车之间重新引入了IPC。尽管如此,应用程序容器的开发人员仍然需要在代码中特别指定网络协议,因为服务代理通常不会更改代理消息的传输协议。

究竟,这些应用程序开发人员应该负责协议处理吗?它们应该处理抽象的服务请求(查询、命令、事件),让服务代理处理协议映射、转码和传输吗?这些问题值得商榷,REST API的通用设计时理解可以作为开始抽象的一个起点。这些只是REST的广泛性可以用来帮助固化后-Web范式的两个领域。

一个不怎么缺乏REST的未来

大肆炒作的技术趋势经常吹嘘它们如何用新方法取代了旧方法。在现实中,软件工程通常是层叠进行演进的。每一个新的创新都为后续的一系列创新奠定了基础。新的API协议(如GraphQL、gRPC和Kafka)将取代在某些分布式场景中使用基于资源、json编码、HTTP传输的消息。然而,REST在分布式系统的发展中留下的遗产不应该只是与其实现细节相关的内容,而更多的应该是令它如此无处不在的相关特征:为通用连接性提供框架、将服务消费者与提供者分离、强调可用性和可访问性。正是这些特征使得REST(最初定义为Web的体系结构样式)成为软件工程的后Web范式的基础。

脚注

  1. 本文的目的不是讨论REST的定义。术语“REST”将用于指代Fielding的原始定义以及HTTP上的CRUD风格的API。

  2. 有关REST/gRPC/GraphQL如何根据上下文决策的实际分析,请阅读Phil Sturgeon的这篇博客。

  3. …而且,在很早的时候,就已经不再满足于将REST只是概括为HTTP上的CRUD了。请参阅这里。

  4. 回到SOAP的二分法,一边是这种有机标准的开发,一边是W3C和OASIS标准的爆炸式增长,它们形成了鲜明的对比,这两个标准出现在2000年初Web服务繁荣的高峰时期。

感谢Mike Amundsen、Erik Wilde、Irakli Nadareishvili和Ronnie Mitra找到了本文中列出的“REST的历史”资源。

关于作者

Matt McLarty是一位卓有经验的软件架构师,领导博通公司CA 科技的API Academy团队。他与组织紧密合作,设计和实现创新的企业级API和微服务解决方案。在软件供应商和客户端的集成和实时事务处理领域,他有着广泛的工作经验。Matt最近与人合著了O 'Reilly的书《微服务体系结构和微服务API安全》。

查看英文原文:Overcoming RESTlessness

持续演进,克服“REST缺乏”相关推荐

  1. 离线实时一体化数仓与湖仓一体—云原生大数据平台的持续演进

    简介:阿里云智能研究员 林伟 :阿里巴巴从湖到仓的演进给我们带来了湖仓一体的思考,使得湖的灵活性.数据种类丰富与仓的可成长性和企业级管理得到有机融合,这是阿里巴巴最佳实践的宝贵资产,是大数据的新一代架 ...

  2. 阿里云孙成浩:生而为云,连接增长——洛神云网络3.0持续演进

    12 月 1 日,第二届中国云网络峰会在线举办,在「云网融合」分论坛上,阿里云智能 云网络产品线副总经理 孙成浩(梵叶)发表<云网络:生而为云,连接增长--洛神云网络 3.0 持续演进>主 ...

  3. 知识图谱前端插件_大型前端项目可持续演进开发的思考

    引言 当谈起这个话题的时候,不得不去想到<人月神话>这本著作中所描述的软件工程思想,其中的最后一段总结论述: 软件工程的焦油坑在将来很长一段时间内会继续地使人们举步维艰,无法自拔.软件系统 ...

  4. 前端调用后端接口 xhr 只看到一次 实际调用两次_持续演进的接口自动化测试方案...

    点击关注"有赞coder" 获取更多技术干货哦- 作者:Henry 部门:美业测试 前言 接口自动化测试是个老生常谈的话题,基本上每个测试团队都会涉及,市面上大部分文章会从如何设计 ...

  5. 网络持续演进不仅是技术活儿,还是一个“哲学问题”

    <纽约时报>曾专门撰文描绘了"Z世代"的成长,以及这一代人将给世界带来的变化.所谓Z世代,是指1996年到2010年间出生的一代人,他们是伴随着智能手机长大的第一代人, ...

  6. 数仓架构的持续演进与发展 — 云原生、湖仓一体、离线实时一体、SaaS模式

    简介: 数据仓库概念从1990年提出,经过了四个主要阶段.从最初的数据库演进到数据仓库,到MPP架构,到大数据时代的数据仓库,再到今天的云原生的数据仓库.在不断的演进过程中,数据仓库面临着不同的挑战. ...

  7. @成都的Coder ,一起探讨终端架构持续演进

    简介:6月19日,mPaaS 盛邀各位 Coder,莅临成都蚂蚁 C 空间,共同探讨面向未来的移动端动态化架构设计思路以及动态化背景下的移动端技术选型趋势. 相约天府蓉城 针对纯原生开发面临的动态发布 ...

  8. 深入理解操作系统内核架构(送书)!

    近年来,我国自主研发操作系统被反复提及.近期,一个计算机领域内非常专业的词来到了几乎所有人的视线内,这就是--微内核.人们对操作系统内核的讨论越来越热烈,甚至有人说我不懂什么叫微内核,什么是宏内核,接 ...

  9. 微内核是什么?宏内核是什么?一文带你了解操作系统内核架构!

    近年来,我国自主研发操作系统被反复提及.近期,一个计算机领域内非常专业的词来到了几乎所有人的视线内,这就是--微内核.人们对操作系统内核的讨论越来越热烈,甚至有人说我不懂什么叫微内核,什么是宏内核,接 ...

最新文章

  1. pandas重命名列名称、数据列名称重命名(Rename Column Names): rename、set_axis、df.columns
  2. python无法调用pygame,python-pycharm无法识别pygame程序包
  3. 对POST提交数据限制的解决方案
  4. 深圳先进院研究生计算机专业,2020年中科院深圳先进技术研究院全日制硕士研究生统考专业说明...
  5. 2015年9月01日【磁盘和文件系统管理】-JY1506402-19+liuhui880818
  6. 稳居商用车ADAS前装第一梯队,这家中国本土供应商靠什么?
  7. 腾讯招python吗_#python 爬取腾讯招聘技术类的招聘信息
  8. 工程职业伦理(2018年秋)学堂在线习题
  9. 记录使用gensim进行词向量增量训练(遇到的几个问题)
  10. 有效运用 Color mask 和开发 Automation material - PART 1
  11. 大数据行业常用的软件工具有哪些?
  12. 如何解决不能绘制网络模型,报错protobuf
  13. 小白用Python抓取豆瓣高评分喜剧电影
  14. 施工现场平面布置及其案例说明
  15. android 定时开机闹钟,win7自动-定时开机、关机(附加定时闹钟)技巧
  16. OpenGL的矩阵变换详解——有图有真相
  17. 程序员最怕的四个字:通宵发布!
  18. xmind2022下载非试用(超详细 图文预警)
  19. Go HTTP包源码阅读 持续更新 0.0
  20. CEPH iSCSI GateWay 编译部署安装

热门文章

  1. asp.net常规页生命周期阶段列表和事件列表
  2. 贝叶斯多元Logistics回归理论基础
  3. 利用反汇编手段解析C语言函数
  4. 控制台和Win32 API程序输出变量地址值
  5. python+requests接口自动化测试框架实例详解教程(米兔888)
  6. Docker部署脚本
  7. Ffmpeg 定位文件(seek file)
  8. jQuery遍历函数总结
  9. python中的定制类(转载)
  10. 那天有个小孩跟我说LINQ(五)转载