写点什么

gRPC vs REST:两种 API 架构风格的对比

  • 2021-06-15
  • 本文字数:3192 字

    阅读完需:约 10 分钟

gRPC vs REST:两种API架构风格的对比

想知道未来是不是 gRPC 的天下?本文会具体介绍两种 API 架构风格:REST 和 gRPC,并讨论它们之间的区别。不过,首先,我们会解释什么是 API,以及为什么它对微服务基础设施而言至关重要。之后,我们会介绍 gRPC 的基础——RPC,并探讨 gRPC 和 REST API 之间的重要差异。根据它们的对比结果,我们最后会分析什么时候应该使用哪种架构类型。

API 是什么


API,即应用程序编程接口。这些接口充当软件中介,为应用程序之间的交互和对话建立特定的定义和规则。API 负责将响应从用户传递到系统,然后从系统返回给用户。听起来还是有点糊涂?


API 的工作机制


假设我们正在预订一个酒店。我们在笔记本电脑上访问酒店预订页面,连接到互联网的这个页面会将数据(我们的请求)发送到服务器。然后,服务器检索数据,解析它,一旦所需的操作得到执行,它就会向我们发送一个响应,并在我们的界面上提供信息。这个过程需要 API 才能实现。


API 指定了一个应用程序(网页或移动应用)可以向另一个应用程序发出的请求类型,并进一步确定:如何发出这些请求;使用哪些数据格式;以及用户必须遵循的实践。


本文会对比 gRPC 和 REST 两大架构风格,因为它们代表了人们创建 API 时最常用的两种架构风格。

API 和微服务


一方面,在单体应用程序中,项目的所有功能都包含在一个单元中,更准确地说是包含在一个代码库中。另一方面,微服务架构由一些较小的服务组成,这些服务使用 HTTP 等协议相互通信。作为微服务架构一部分的组件服务通过 API 相互通信和交互。换句话说,API 允许集成到微服务应用程序中的所有服务互相连接和通信。


最常用的架构风格是 REST API。但构建 API 时主要有 3 种模型:RPC(远程过程调用)、REST(表征状态传输)和 GraphQL。在本文中,我们将重点介绍前两个。

什么是 RPC?


RPC 使用客户端-服务器模型。请求服务器(换句话说就是客户端)请求一条消息,该消息由 RPC 转换并发送到另一台服务器。服务器收到请求后将响应发送回客户端。当服务器处理这个调用时,客户端被阻塞,服务器内部的消息传递被隐藏。


此外,RPC 允许客户端以特定格式请求函数,并以完全相同的格式接收响应。在 URL 中可以找到使用 RPC API 提交调用的方法。RPC 支持本地和分布式环境中的远程过程调用。


与 REST API 一样,RPC 还建立了交互规则以及用户如何提交“调用”(请求)以调用方法与服务通信和交互的机制。

什么是 REST?


使用 REST API 时,来自后端数据的响应通过 JSON 或 XML 消息格式传递给客户端(或用户)。这种架构模型倾向于遵循 HTTP 协议。然而,在维护 RCP 模型的同时,RCP 设计也时常从 HTTP 中汲取一些想法。事实上,不管使用的是哪种模型(RPC 或 REST),大多数现代 API 实现都将 API 映射到相同的 HTTP 协议时。


当 REST API 公开可用时,每个集成微服务应用程序的服务都可以作为资源呈现给用户/客户端,资源可以通过以下 HTTP 命令访问:GETDELETEPOSTPUT

什么是 gRPC?


gRPC 是 Google Remote Procedure Call 的简写,是基于 RCP 架构的变体。该技术遵循一个使用 HTTP 2.0 协议的 RPC API 实现,但 HTTP 不会呈现给 API 开发人员或服务器。因此,开发人员无需担心 RPC 概念如何映射到 HTTP,从而降低了复杂性。


总的来说,gRPC 旨在加快微服务之间的数据传输。它的基础方法是确定一个服务,建立方法和相应的参数来实现远程调用和返回类型。


此外,它以一个 IDL(接口描述语言)表示 RPC API 模型,这为确定远程过程提供了更直接的方法。默认情况下,IDL 使用 Protocol Buffers(但也可以使用其他替代方案)来描述服务接口以及负载消息的结构。

gRPC 与 REST:对比


现在,我们对 gRPC 和 REST 有了一个初步认识,下面我们来看看它们的主要区别。

HTTP 1.1 vs HTTP 2


REST API 遵循一个通常基于 HTTP 1.1 构建的请求-响应通信模型。不幸的是,这意味着如果一个微服务收到来自多个客户端的多个请求,该模型必须每次只处理一个请求,拖慢了整个系统的速度。REST API 也可以构建在 HTTP 2 上,但通信的请求-响应模型保持不变,这使得 REST API 无法充分利用 HTTP 2 的优势,例如流式通信双向支持


gRPC 没有面临类似的障碍。它建立在 HTTP 2 之上,且遵循客户端-响应通信模型。这让它支持双向通信和流式通信,因为 gRPC 能接收来自多个客户端的多个请求,并通过不断地流式传输信息来同时处理这些请求。此外,gRPC 还可以处理“一元”交互,例如构建在 HTTP 1.1 上的交互。


总之,gRPC 能处理一元交互和多种类型的流:


  • 一元:客户端发出单个请求并接收单个响应。

  • 服务器流:服务器对客户端的请求响应一个消息流。当全部数据发送完毕后,服务器会再发送一条状态消息来完成流程。

  • 客户端流:客户端向服务器发送一个消息流,并接收单个响应消息。

  • 双向流:客户端和服务器的两个流互相独立,也就是说它们都能以任何顺序传输消息。客户端负责发起并结束双向流。


流类型

浏览器支持


这可能是 REST 相对于 gRPC 的主要优势之一。一方面,所有浏览器都完全支持 REST。另一方面,gRPC 获得的浏览器支持仍然非常有限。


不幸的是,它需要 gRPC-web 和一个代理层来执行 HTTP 1.1 和 HTTP 2 之间的转换。因此,gRPC 主要用于内部/私有系统(特定组织的后端数据和应用程序功能中的 API 程序)。

负载数据结构


如前所述,gRPC 默认使用 Protocol Buffers 来序列化负载数据。这个方案更轻便,因为它支持高度压缩的格式并减少了消息的大小。此外,Protobuf(或 Protocol Buffer)是二进制的;它对结构化数据进行序列化和反序列化,以便通信和传输。换句话说,强类型消息可以自动从 Protobuf 转换为客户端和服务器的编程语言。


相比之下,REST 主要依靠 JSON 或 XML 格式来发送和接收数据。事实上,即使它不强制要求任何结构,JSON 也是最流行的格式,因为它具有灵活性和发送动态数据的能力,而不必遵循严格的结构。使用 JSON 的另一显著优势是其人类可读水平,这方面 Protobuf 尚无法与之竞争。


尽管如此,JSON 在数据传输方面并不够轻量或快速。其原因在于,在使用 REST 时,必须将 JSON(或其他格式)序列化并转换为客户端和服务器端使用的编程语言。这在传输数据的过程中增加了一个额外步骤,从而可能会损害性能并增加出现错误的可能性。

代码生成功能


与 gRPC 不同,REST API 不提供内置代码生成功能,这意味着开发人员必须使用 Swagger 或 Postman 等第三方工具为 API 请求生成代码。


相比之下,gRPC 由于其 protoc 编译器而具有原生代码生成功能,该编译器与多种编程语言兼容。这对于集成了以不同语言和平台开发的各种服务的微服务系统来说尤其方便。此外,内置的代码生成器还有助于创建 SDK(软件开发工具包)。

gRPC 与 REST:对比表



何时使用 gRPC,何时使用 REST?


如前所述,尽管 gRPC 提供了许多优势,但它有一个主要障碍:浏览器兼容性低。因此,gRPC 的用例一般局限在内部/私有系统。


相比之下,正如我们所讨论的那样,REST API 可能有其缺点,但它们仍然是连接基于微服务的系统的最流行的 API。此外,REST 遵循 HTTP 协议标准化并提供通用支持,使这种 API 架构风格成为 Web 服务开发以及应用程序和微服务集成的首选。然而,这并不意味着我们应该忽视 gRPC 的应用场景。


gRPC 架构风格具有很多值得(并且应该)探索的有前途的特性。它是处理多语言系统和实时流的绝佳选择,例如,当运营需要轻量级消息传输(可以由序列化 Protobuf 消息支持)的 IoT 系统时,gRPC 就很合适。此外,gRPC 也可以考虑用于移动应用程序,因为它们不需要浏览器,且消息体积更小,不会拖慢移动设备的速度。

结论


gRPC 提供了很多优势。与 REST 不同,它可以充分利用 HTTP 2,使用多路复用流并遵循二进制协议。此外,由于 Protobuf 消息结构,它还具备性能优势,支持多语言环境的内置代码生成功能也是一大好处。这些因素使 gRPC 成为了一种很有前途的 API 架构风格。


尽管如此,浏览器支持不足使 gRPC 很难匹敌 REST 的通用支持能力。REST 仍然是微服务系统中的粘合剂,是最流行的解决方案。因此它很可能会存在很长时间,而且说实话,它是一个非常成熟和成功的架构。


原文链接:


https://www.imaginarycloud.com/blog/grpc-vs-rest/?fileGuid=3WQyP6YQDvcqhcXx

2021-06-15 15:4219655
用户头像
王强 技术是文明进步的力量

发布了 822 篇内容, 共 428.5 次阅读, 收获喜欢 1749 次。

关注

评论 2 条评论

发布
用户头像
RPC or RCP ?

RCP

2021-06-25 11:18
回复
没有更多了
发现更多内容

【CSS】:什么是z-index属性?该属性有哪些取值类型?

翼同学

CSS 前端 样式设置 10月月更

mysql中的事务隔离级别序列化如何实现

知识浅谈

MySQL 隔离级别 10月月更

【一Go到底】第一天---初识Goooooooooooooooooooooooo

指剑

Go go并发 10月月更

操作系统导论:分页

小白钊钊

操作系统 java; 10月月更

Spring Boot 集成 Redis 配置 MyBatis 二级缓存

微枫Micromaple

redis 缓存 mybatis springboot 10月月更

跟随一组图片,了解Go Channel的底层实现

董哥的黑板报

Go 后端 服务端 操作系统 runtime

spring-cloud-kubernetes与SpringCloud Gateway

程序员欣宸

Kubernetes spring-cloud 10月月更 spring-cloud-kubernetes

【结构体内功修炼】结构体内存对齐(一)

Albert Edison

C语言 结构体 10月月更 内存对齐

大画 Spark :: 网络 (8)-Spark 网络中的“四次握手”Driver 如何获取 Executor 的 EndpointRef 烧脑

dclar

大数据 hadoop spark 源代码 spark源码

ESP32-C3 学习测试 蓝牙 篇(四、GATT Server 示例解析)

矜辰所致

蓝牙 ESP32-C3 10月月更 GATT

【牛客刷题-算法】1-算法入门-数据结构-栈

清风莫追

算法与数据结构 10月月更

体验 Orbeon form PE 版本提供的 JavaScript Embedding API

汪子熙

Java SAP commerce 10月月更 oberon

一起玩OptaPlanner-Study,玩转第一个程序

成长兔🐇

【愚公系列】2022年10月 Go教学课程 015-运算符之赋值运算符和关系运算符

愚公搬代码

10月月更

【LeetCode】重新格式化电话号码Java题解

Albert

LeetCode 10月月更

微服务稳定性保障

穿过生命散发芬芳

微服务 10月月更

[架构实战] 学习笔记二

爱学习的麦子

在vue的v-for中,key为什么不能用index?

bb_xiaxia1998

Vue

从特斯拉人形机器人亮相看AI人工智能模型落地面临的两个难题

felix

落地 机器人 AI人工智能

Go学习之路-1.认识GO语言

子不语Any

Go 后端 10月月更

能不能手写Vue响应式?前端面试进阶

bb_xiaxia1998

Vue

Qt解压带有密码的加密文件

中国好公民st

c++ Qt Company 10月月更

《零代码教练指南》正式发布

明道云

架构师的十八般武艺:线上运维

agnostic

运维

Python应用之计算三角形面积

梦笔生花

10月月更 Python代码 计算三角形面积

When allowCredentials is true, allowedOrigins cannot contain the special value ___ since that cannot be set on the _Access-Contr

共饮一杯无

Java springboot 10月月更

今日国庆,祝福祖国!【文末超级福利】

图灵社区

读书 国庆节

今日国庆,祝福祖国!【文末超级福利】

图灵教育

读书 国庆节

Java中的自旋锁和适应性自旋锁是什么意思?其分类依据是啥?

wljslmz

Java 自旋锁 10月月更 适应性自旋锁

OpenHarmony如何控制屏幕亮度

坚果

OpenHarmony 10月月更

存储优化--分区与冷热分离

喵叔

10月月更

gRPC vs REST:两种API架构风格的对比_架构_André Santos_InfoQ精选文章