SOAP vs REST vs gRPC vs GraphQL
就比较而言,这可能看起来有点奇怪。虽然前两个是(曾经是)传统的相互竞争的“标准”,但后两个在范围上略有不同。
它们的共同之处在于都涉及数据操作控制权的转移。它们都允许外部实体在一定范围内访问您的数据。
肥皂
“简单对象访问协议”(尽管这个含义在很大程度上已被人们遗忘,因为它一点也不简单)是最古老的数据访问系统,也是我大学时代的噩梦。
它通过 HTTP 使用 XML 内容进行通信(主要是通过 HTTP,但传输不是标准的一部分,因此它可以通过任何方式使用),其特定目的是调用服务公开的过程。
这要求服务在定义服务的 WSDL 中定义可用的过程、参数和类型、内容格式、响应等,同时还需要许多其他 XML 衍生文件(XSD 等)来定义自定义类型和对象。
我敢肯定,你已经看到了简约之美消亡的迹象。
优势
SOAP 允许基于 XML 生成代码。XML 曾经是一种流行且应用广泛的标准,具有很高的灵活性(例如:命名空间)。作为一种基于文本的标准,它易于调试,并且在传输方面没有任何限制。由于过程是在 WSDL 中描述的,因此该文件充当了消息和类型的约束性契约。
缺点
XML 非常冗长,消息大小往往呈指数级增长。因此,SOAP 只能单向传输(也就是说,客户端不能同时充当服务器,反之亦然——即使两个应用程序都可以充当 Web 服务器)。现代语言对代码生成的支持不足(Java、Python 和 C# 是最佳选择,而 Go/Rust/PHP/Elixir 等语言的 SOAP 实现则令人沮丧)。
总而言之,SOAP 几乎已经消亡,取而代之的是更灵活、更高效的通信方式(尽管在参与了一些保险和银行相关的项目后,我的噩梦又回来了)。
休息
提到“Web API”,大多数人首先想到的可能是表述性状态转移(REST)。事实上,它非常流行,以至于人们一提到“API”,首先想到的就是它,而忽略了Web(或HTTP)部分。
作为一项标准,REST 出人意料地轻量级,因为它仅规定了如何使用 HTTP 和 HTTP 概念(动词、代码、状态等)来访问位于不同 URI 的远程实体。这催生了许多围绕 REST 的最佳实践,这些实践处理了未明文规定的问题:如何定义和组织 URI、给定 URI 下操作的数据边界、如何封装数据、如何以及返回什么数据等等。
REST 服务的另一个重要特性是无状态性:请求之间不应保留任何上下文,每个请求都是独立处理的,并且必须具有自己的最终性。
虽然 JSON 是 REST 数据最常见的内容类型,但 XML 也并非闻所未闻,而且 HTML 本身也是可用的。
优势
基于现有 HTTP 标准构建的 REST API 既具有灵活性,也存在一些限制。大多数传输相关的问题都由现有标准处理,并随着标准的发展而演进。动词与操作相关联(例如,简化了 CRUD 操作的映射),实体为 URI 赋予名称和含义。简单的约定使得与 REST API 的交互相当直接。JSON
使得 REST 在前端服务中尤其易于使用,因为 JavaScript 无处不在,数据到对象的转换几乎是即时的。
此外,JSON 也非常易于阅读和调试。
缺点
实际上,REST 服务很少能像预期那样高效。关于何时使用哪些动词以及暴露的实体是否与数据层中建模的数据相同(提示:不要这样做,不要泄露这类细节,使用 DTO 才是王道)的争论从未停止。
这种灵活性往往导致实现混乱,而且消息结构也没有统一的规范。
我尤其反感的是,有些人无论如何都返回 HTTP 200 响应,却在响应体中编码错误状态。这不就是 SOAP 时代的做法吗!
GRPC
gRPC 远程过程调用是一个递归缩写,它定义了一种方法,该方法利用了 HTTP/2 的所有优势,并且由于它使用二进制格式(编译后的协议缓冲区)进行传输,因此效率极高。
与 SOAP 类似,gRPC 的目标是实现过程调用而不是数据交互,因此在概念上与 SOAP 有些相似。
这是谷歌的创意。
优势
非常高效。它充分利用了 HTTP/2 的所有优势,例如可以同步发送数据(等待响应)、可以进行流式传输、可以进行多路复用,所有这些都可以在同一连接上完成。再加上二进制消息体积非常小,在对性能要求极高的场合,它简直是完美之选。
代码生成功能让配置变得轻而易举,而 HTTP/2 需要 TLS,因此你只能获得最低限度的安全保障。
缺点
由于消息是二进制的且不可读,因此很难调试。虽然它被多种语言支持,但某些语言存在限制(例如:您不能使用 PHP gRPC 服务器,只能使用客户端),而且由于 HTTP/2 的特性,目前前端应用程序无法直接支持它。
由于您必须(也应该)在所有地方都使用 TLS,因此您需要将其纳入设置要求中(无论是从已知的 CA 获取内部使用的证书,还是创建自己的内部 CA 来颁发证书,但您都需要将其添加到您的基础架构/容器等的受信任列表中)。
GraphQL
GraphQL介于REST和gRPC之间。它旨在通过自身的查询语言简化数据请求,并将控制权交给客户端。
这是Facebook的创意。
优势
它对 JSON 的依赖使其在某种程度上类似于 REST,但其优势在于自适应查询,这意味着您可以根据需要请求所需数据 => 无需再为获取所有必要信息而进行多次请求。
它具有模式验证和类型检查功能,因此从这个意义上讲,它与 gRPC 的定义方式有些接近。
缺点
所有这些灵活性都对缓存能力造成了影响。几乎没有 GraphQL 请求是相似的,因此不需要缓存。
尽管名称如此,但它并不完全是一个图形接口。例如,你无法获取父实体的所有祖先。
这样做有什么意义?
我一直深受 SOAP 的困扰,而且我觉得我不是唯一一个。我想提醒大家注意这个仍然潜伏在 Web 开发阴暗角落里的祸害。
我一直是一名专注的 REST 开发人员,花了数年时间才摸索出一套系统化的 API 设计方法。虽然还不错,但我真的觉得应该有更好的方法。尽管有各种最佳实践等等,但绝大多数项目最终还是会陷入某种可控的混乱状态,而缺乏可验证的消息传递契约更是致命的缺陷。
我试用过 GraphQL,也看到了它的价值。它非常适合前端开发(从它与 Facebook 的渊源可以看出,它与 React 非常契合),但它是一条单向通道。我无法想象用 GraphQL 来实现微服务之间的通信。它比 REST 更结构化,但其优势几乎都体现在客户端。
我对 gRPC 越来越感兴趣了。根据你使用的工具,可能会有一些额外的开销。PHP 的配置和构建过程grpc_php_plugin很麻烦,而且严重依赖于操作系统(抱歉 Windows 用户,你们可能需要自己动手搭建 WSL2——不过如果我说错了请告诉我,虽然我上次检查时预构建的插件已经弃用了)。用 Go 语言开发 gRPC 非常棒(毕竟是谷歌出品),但用 Rust/.NET/Elixir 也不错。
我只希望我能像当初养成使用 REST 的习惯那样,养成使用 GRPC 的习惯。
文章来源:https://dev.to/andreidascalu/soap-vs-rest-vs-grpc-vs-graphql-1ib6