gRPC-Web 是一个官方提供的技术标准和相关实现,它允许直接从浏览器中的 JavaScript 应用程序调用 gRPC 服务。我们可以把它看作是 gRPC 在浏览器环境中的适配器。

简单来说,它架起了一座桥梁,让基于浏览器的前端应用也能享受到 gRPC 带来的所有优势。


gRPC-Web 解决了什么问题?

在 gRPC-Web 出现之前,gRPC 主要用在服务端之间(如微服务架构)的通信。浏览器无法直接使用 gRPC,原因主要有两个:

  1. HTTP/2 的限制:gRPC 构建在 HTTP/2 之上,但浏览器中的 XMLHttpRequest 或早期的 Fetch API 无法提供对 HTTP/2 请求体的足够细粒度的控制,无法发送 gRPC 使用的二进制协议缓冲区载荷。
  2. 浏览器 API 限制:浏览器环境不允许 JavaScript 代码直接使用 HTTP/2 的某些高级特性(如 trailers,gRPC 用它来传输状态码和错误信息)。

因此,传统的 Web 前端要与后端通信,只能使用 RESTful API 或 GraphQL,并通过 JSON 进行数据交换。虽然这些技术很成熟,但与 gRPC 相比,它们在性能、类型安全和开发效率上有所欠缺。

gRPC-Web 的出现,就是为了让浏览器也能成为 gRPC 生态中的一等公民。


gRPC-Web 的核心工作原理

gRPC-Web 没有试图让浏览器直接理解 gRPC,而是采用了一种“代理”或“转码”的架构:

  1. 前端客户端:浏览器的 JavaScript 代码使用一个特殊的 gRPC-Web 客户端库。这个库会像普通 gRPC 客户端一样,让我们调用方法、传递强类型的请求对象。
  2. 编码:gRPC-Web 客户端库将我们的调用和参数编码成一种浏览器友好的格式(通常是二进制 application/grpc-web 或文本 application/grpc-web+json)。
  3. 发送 HTTP/1.1 请求:编码后的数据通过标准的浏览器 XMLHttpRequestFetch API,以 HTTP/1.1 协议发送出去。
  4. gRPC-Web 代理/Envoy:请求首先到达一个特殊的代理。这个代理最常见的实现是 Envoy 代理(它内置了 grpc_web 过滤器)。代理的作用是“翻译”:它将收到的 HTTP/1.1 gRPC-Web 请求,转换为后端服务能够理解的纯 gRPC(HTTP/2)请求
  5. 后端服务纯 gRPC 请求被路由到真正的 gRPC 后端服务。对于后端服务来说,它完全不知道浏览器的存在,它认为自己只是在和一个普通的 gRPC 客户端通信。
  6. 响应路径:后端返回的纯 gRPC 响应,被代理再次“翻译”成浏览器可以理解的 gRPC-Web 格式,并通过 HTTP/1.1 返回给浏览器端的 gRPC-Web 客户端。

主要特点和优势

  1. 强类型和代码生成:和 gRPC 一样,我们需要使用 .proto 文件定义服务接口,然后通过工具生成客户端存根代码。这保证了前后端数据类型的一致性,避免了手动解析 JSON 可能出现的错误。
  2. 高性能、载荷小:默认使用 Protocol Buffers 进行二进制序列化,相比 JSON 体积更小,序列化/反序列化速度更快,节省带宽,提升性能。
  3. 双向流:gRPC-Web 规范支持客户端流、服务器端流和双向流。虽然浏览器实现上对流的支持在不断完善,但它已经能够实现类似实时消息推送的功能。
  4. 现代化的开发体验:与 TypeScript 结合得天衣无缝,提供了极佳的代码自动补全和类型检查体验。
  5. 生态系统集成:可以自然地融入基于 gRPC 的微服务生态系统,前端可以直接调用微服务后端的接口,而无需再为前端专门编写一层 RESTful API 网关。

与普通 gRPC 和 REST 的对比

特性 gRPC-Web 普通 gRPC REST/JSON
传输协议 HTTP/1.1 或 HTTP/2 HTTP/2 HTTP/1.1
数据格式 Protocol Buffers (二进制) Protocol Buffers (二进制) JSON (文本)
浏览器支持 ,通过特定客户端库 ,原生支持
强类型接口 ,通过 .proto 文件 ,通过 .proto 文件 ,依赖文档和约定
流式通信 支持 (客户端/服务端/双向) 支持 (客户端/服务端/双向) 有限 (主要通过 SSE/WebSockets)
性能 高 (二进制,载荷小) 非常高 (二进制,HTTP/2) 中等 (文本,载荷大)

总结

gRPC-Web 是一项关键技术,它成功地将 gRPC 的强大功能引入了浏览器环境。 它通过一个轻量级的代理“翻译”层,解决了浏览器与 gRPC 协议之间的兼容性问题。

如果你正在构建一个前后端分离的现代 Web 应用,并且后端已经或计划使用 gRPC,那么 gRPC-Web 是一个非常值得考虑的方案。它能为你带来更好的性能、更强的类型安全性和更高的开发效率。


孟斯特

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
腾讯云开发者社区:孟斯特