速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

替换 Rest?不,软件工程应该构建成熟的 REST 生态

  • 2019-03-06
  • 本文字数:4425 字

    阅读完需:约 15 分钟

替换Rest?不,软件工程应该构建成熟的REST生态

本文关键点:


  • 在过去的几年中,软件开发社区中出现了越来越多的反 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 服务繁荣的高峰时期。


英语原文:


https://www.infoq.com/articles/overcoming-restlessness


2019-03-06 09:1912880

评论

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

成都开发者Meetup|聚焦云原生开源,点亮企业创新活力

阿里巴巴云原生

阿里云 容器 微服务 云原生

OpenTiny 跨端、跨框架组件库升级TypeScript,10万行代码重获新生

华为云开发者联盟

Vue 前端 华为云 华为云开发者联盟 企业号 4 月 PK 榜

你的 Kubernetes 安全吗?最新benchmark的重要趋势解读

HummerCloud

Kubernetes k8s

扯下@EventListener这个注解的神秘面纱。

why技术

Java 源码

ZBC 荣登OKX涨幅榜前列,月内涨幅逾六成

股市老人

Atlassian后Server时代 | Server版vs.数据中心版,二者的区别在哪里?

龙智—DevSecOps解决方案

Atlassian 数据中心版 server版

又搞事!阿里400页JDK并发源码指南,再次被GitHub置顶了!

做梦都在改BUG

Java jdk 多线程 高并发 源码剖析

玩转Github:三分钟教你如何用 Github 快速找到优秀的开源项目

程序知音

Java GitHub 编程语言 后端技术

火山引擎云原生数据仓库ByteHouse技术白皮书V1.0(上)

字节跳动数据平台

大数据 数据仓库 云原生 实时数仓 企业号 4 月 PK 榜

雀氏牛,Alibaba分布式微服务成长手册,GitHub已开源

做梦都在改BUG

Java 分布式 微服务

企业云管平台是什么?有什么用?

行云管家

云计算 云管理 云管

什么是可信云?通过可信云评估意味着什么?

行云管家

可信云

大模型高效开发的秘密武器:大模型低参微调套件MindSpore PET

华为云开发者联盟

人工智能 华为云 大模型 华为云开发者联盟 企业号 4 月 PK 榜

一份深入解析Java虚拟机HotSpot手册,让我卷成美团架构师

程序知音

Java JVM java架构师 hotspot Java进阶

【重磅发布】易观千帆用户体验分析产品领先版正式发布

易观分析

金融 银行 用户分析

从 OSPO 角度思考开源治理问题——蚂蚁集团开源办公室负责人边思康

开源雨林

🔥InfoQ写作社区三周年主题征文火热开启

InfoQ写作社区官方

热门活动 三周年征文

Gartner最新报告,分析超大规模边缘解决方案

阿里云CloudImagine

云计算 边缘计算 边缘云

“字节”再次起跳!内部651页剖析HotSpot 源码手册,GitHub已开源

做梦都在改BUG

Java JVM 虚拟机 hotspot

MySQL数据库和Redis缓存一致性的更新策略

做梦都在改BUG

Java MySQL 数据库 redis 缓存

[直播预告]行云管家堡垒机V7.0版本说明会

行云管家

行云管家

Docker教程:如何将Helix QAC创建为一个容器并运行?

龙智—DevSecOps解决方案

Docker 容器 Helix QAC 静态代码扫描

SpringBoot整合RocketMQ,老鸟们都是这么玩

做梦都在改BUG

Java RocketMQ Spring Boot

LED显示屏十大应用领域值得你收藏

Dylan

LED显示屏 户外LED显示屏 户内led显示屏

文献管理软件:EndNote 20 v20.5激活版

真大的脸盆

Mac Mac 软件 文献管理 文献管理工具

浅析云原生时代的服务架构演进

华为云开发者联盟

后端 开发 华为云 华为云开发者联盟 企业号 4 月 PK 榜

从零学习SDK(4)使用SDK创建一个简单的应用程序

MobTech袤博科技

简化你的代码,提高生产力:这10个Lambda表达式必须掌握

做梦都在改BUG

Java Lambda

如何用 YonBuilder 构建线索管理应用?

YonBuilder低代码开发平台

替换Rest?不,软件工程应该构建成熟的REST生态_语言 & 开发_Matt McLarty_InfoQ精选文章