GRPC 与 REST 有何不同?

Posted

技术标签:

【中文标题】GRPC 与 REST 有何不同?【英文标题】:How is GRPC different from REST? 【发布时间】:2017-09-26 16:47:54 【问题描述】:

我正在阅读这个explanation of GRPC,这个图表很有趣:

传输层如何工作?如果它是通过网络... 为什么它被称为 RPC?更重要的是,这与为服务层(客户端中具有发出 http 请求的方法的类)实现 API 的 REST 有何不同?

【问题讨论】:

«如果是通过网络...为什么叫 RPC»——因为 RPC 是远程过程调用,而“远程”完全可以表示“在另一台主机上”。 而休息并不意味着在另一台主机上? 既不需要网络/远程主机,也不需要排除它,因为两者都忘记了客户端/服务器所在的位置。这是传输层的问题。 【参考方案1】:

传输层在 TCP/IP 之上使用 HTTP/2 工作。它允许更低延迟(更快)的连接,可以利用从客户端到服务器的单个连接(这可以更有效地使用连接并可以更有效地使用服务器资源。

HTTP/2 还支持双向连接和异步连接。因此,服务器可以有效地与客户端联系以发送消息(异步响应/通知等)。

虽然 REST 和 gRPC 都可以生成客户端/服务器存根(对 REST 使用 swagger 之类的东西),但 REST 具有一组有限的主要“函数”调用(或动词):

+-----------+----------------+ | HTTP 动词 |增删改查 | +-----------+----------------+ |发布 |创建 | |获取 |阅读 | |放 |更新/替换 | |补丁 |更新/修改 | |删除 |删除 | +-----------+----------------+

而 gRPC 您可以定义任何类型的函数调用,包括同步/异步、单向/双向(流)等。

客户端使用 gRPC 调用本地方法。对程序员来说,看起来您是在进行本地调用,但底层(自动生成的客户端存根)将调用发送到服务器。在服务器看来,它的方法是在本地调用的。

gRPC 负责所有底层管道并简化编程范式。然而,对于一些敬业的 REST 纯粹主义者来说,这似乎过于复杂了。 YMMV

【讨论】:

所以,快速提问:在 REST 中,您还可以调用任何类型的函数。例如,在 Rails 中,我可以向非 RESTful 端点发送一个 GET 请求,并且除了获取资源之外还可以做一些事情。我可以从那个非 RESTful 端点启动任何功能。我还可以在 REST 中创建看似调用本地方法的服务,但实际上是在对端点进行 http 调用。因此,它们之间的差异并没有那么大……至少在传输层上。还是他们? REST/RESTful 在 HTTP 上运行,gRPC 在 HTTP/2 上运行(如 WebSocket)。使用 Swagger 的代码生成器可以为 REST 生成客户端和服务器存根,gRPC 使用 proto 文件来生成它的存根(与旧的 WSDL/SOAP 方法不同)。 proto 文件定义了类型,因此生成的客户端/服务器存根是类型安全的。在移动设备上,gRPC 连接非常高效,因为它可以与来自移动应用的任何其他并发连接共享相同的底层 HTTP/2 套接字。 这是一个很好的 gRPC 介绍:medium.com/square-corner-blog/grpc-reaches-1-0-85728518393b 这是一个 gRPC 的演示:github.com/mmcc007/go Jwan622 和 mmccabe:使用 Superglue 2.1 库,我可以用苹果和橘子建造房子。在某些时候,我们必须为工作选择正确的工具,并始终寻求将软件系统的复杂性降至最低。请记住,删除代码始终是一种性能优化;) 在我看来,像 RESTful API 之类的东西一直是在旧协议上使用的“黑客”。如果出现一些让我使用更适合现代语言的堆栈并且仍然不知道客户具体使用哪种语言并显着提高性能的东西,那么我将成为第一个加入潮流的人! 【参考方案2】:

我一直觉得 gRPC 和 REST 绝对是两个不同的东西。

REST 最适合面向资源的服务。 否则我们可以使用 gRPC 来获得高性能。

REST 是互联网级别的,用于最终用户与我们的服务交谈。 gRPC 是 Intranet 级别的,用于内部服务之间的对话。

REST 具有遵循的应用程序语义。 gRPC 没有提供任何东西,您应该从头开始构建所有内容。

【讨论】:

【参考方案3】:

REST 不需要 JSON 或 HTTP/1.1

您可以轻松构建一个 RESTful 服务,通过 HTTP/2 发送 protobuf 消息(或其他)

您可以构建通过 HTTP/2 发送 JSON 的 RESTful 服务

您可以构建通过 HTTP/1.1 发送 protobuf 消息的 RESTful 服务

RESTful 服务不是 HTTP/xx 之上的“黑客”,它们是遵循使任何版本的 HTTP 成功的基本架构原则的服务(如 GET 请求的可缓存性和 PUT 请求的可重放性)。

gRPC、SOAP 等。 al 更像是 hack - 在 HTTP 之上的 hack,通过 HTTP 隧道 RPC 样式的服务,绕过防火墙和中间盒限制。这不一定是坏事。有时您可能需要 RPC 样式的服务而不是 REST 服务,而我们必须生活在一个中间盒难以替代的世界中。

如果您没有时间阅读 REST 的实际定义: https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

总有 TLDR;***上的版本:

https://en.wikipedia.org/wiki/Representational_state_transfer

如果您需要 RPC 样式的服务,那么 gRPC 确实很棒。如果您想在 Web 上生活,或者您想要 RESTful 风格服务带来的所有好处,那么构建一个 RESTful 风格服务。如果在你的 restful 服务中序列化/反序列化 JSON 格式的数据太慢,那么使用 protobuf 或其他什么都可以。

如果 gRPC 是任何东西的第 2 版,那么它就是 SOAP 的第 2 版。一种并不可怕的东西,比如 SOAP。

而且,不,您不能只在 GET 请求中“调用任何函数”,并拥有 RESTful 服务。

最后一件事:如果您要在 RESTful 服务上使用 protobuf,请正确使用内容类型标头等。这样,您可以轻松同时支持 JSON 和 protobuf。

现在离开我的 SOAP 盒子.. ;)

【讨论】:

您是在暗示不能使用 gRPC 创建 RESTful 服务吗? RTFM 引用菲尔丁的论文是矫枉过正,但反响很好。【参考方案4】:

gRPC 相对于 REST 的最大优势是它对 HTTP/2 的支持超过了祖父 HTTP 1.1。那么 HTTP/2 相对于 HTTP 1.1 的最大优势是,'HTTP/2 允许服务器“推送”内容'......

【讨论】:

服务器推送不需要HTTP/2。 您能说得更具体些吗?这是讨论 HTTP/2 服务器推送的 wiki:en.wikipedia.org/wiki/HTTP/2_Server_Push 抱歉,我不是指 HTTP 2 服务器推送,我指的是流式回复。还有其他方法可以进行流式回复,例如古老的长轮询或 websocket。 gRPC服务端不发送HTTP/2"push",gRPC客户端忽略HTTP/2"push"。所以gRPC继承自HTTP/2的优点不应该包括"push"。 HTTP/1.1 和 HTTP/2 不在此列,gRPC 使用 HTTP/2 只是作为一种传输机制,所有 HTTP/2 中的应用程序语义在 gRPC 中都是无用的。许多基于 HTTP 的新协议只是因为它对防火墙友好,参见 SOAP、gRPC、websocket ...

以上是关于GRPC 与 REST 有何不同?的主要内容,如果未能解决你的问题,请参考以下文章

gRPC 与 REST

REST、HTTP 和 gRPC 的正确分类是啥?

什么是gRPC?

REST 与 gRPC:我啥时候应该选择其中之一?

RPC与REST对比指南

DND和DDM有何不同?