gRPC 网关设计实战:同时支持 gRPC 和 REST 客户端
gRPC Gateway Design in Practice: Supporting Both gRPC and REST Clients
| Kevin | 2026-09-10T21:38:00
我们的微服务内部通信用 gRPC,但外部客户端需要 REST。用 grpc-gateway 实现了同时支持两种协议的方案,一套 proto 文件生成两套接口。
Our microservices use gRPC internally but external clients need REST. Implemented dual-protocol support with grpc-gateway, generating both interfaces from one proto file.
微服务之间用 gRPC 通信性能很好,但问题是外部客户端(浏览器、小程序)没法直接调 gRPC。之前我们是单独维护一套 REST 接口做转发,维护成本很高。后来用 grpc-gateway 一次性解决了。 grpc-gateway 的思路 核心思想是在 proto 文件里通过注解定义 REST 映射,然后自动生成一个 HTTP 反向代理: syntax = "proto3"; import "google/api/annotations.proto"; service UserService { rpc GetUser(GetUserRequest) returns (User) { option (google.api.http) = { get: "/api/v1/users/{id}" }; } rpc CreateUser(CreateUserRequest) returns (User) { option (google.api.http) = { post: "/api/v1/users" body: "*" }; } } 编译后会生成 gRPC 服务端代码和一个 HTTP 网关,REST 请求自动转换为 gRPC 调用。 架构 Browser/App → HTTP Gateway (REST) → gRPC Service Internal Services → gRPC Service (直连) 外部走 REST,内部走 gRPC,服务端只需要实现一次业务逻辑。 踩坑记录 1. 错误码映射 gRPC 有自己的错误码体系(NOT_FOUND、INVALID_ARGUMENT 等),需要映射成 HTTP 状态码。grpc-gateway 默认有映射,但有些业务错误码需要自定义。 2. 流式接口 gRPC 的 server streaming 可以映射成 SSE(Server-Sent Events),但 client streaming 和双向 streaming 没法直接用 REST 表达。这些场景只能走 gRPC 或 WebSocket。 3. 文件上传 proto 里定义 bytes 字段传文件不太方便,大文件还是单独做一个 REST 上传接口比较实际。 效果 推行三个月后,接口维护成本降了一半以上。以前改一个接口要改 proto + REST controller 两个地方,现在只改 proto 就行。
Used grpc-gateway to support both gRPC (internal) and REST (external) from a single proto definition. Architecture REST requests hit the HTTP gateway which auto-converts to gRPC calls. Internal services connect directly via gRPC. Only one business logic implementation needed. Pitfalls gRPC-to-HTTP error code mapping needs customization. Streaming RPCs have limited REST support. Large file uploads still need dedicated REST endpoints. Result: API maintenance cost cut by 50% - changes only need to be made in proto files.