本页目录
tonic (gRPC)
gRPC 用 protobuf 定义强类型的 service 接口——改了 .proto,所有调用方必须更新否则编译失败(编译器验证的合约,不是约定)。tonic 是 Rust 的 gRPC 实现,codegen 从 .proto 生成 Rust trait,streaming 类型(unary/client/server/bidi)和 interceptor 层分别对应不同的使用场景和横切逻辑。
gRPC 与 REST 的区别
REST 基于 HTTP 方法 + URL 表达操作,payload 通常是 JSON。gRPC 用 protobuf 定义强类型的 service 接口,payload 是二进制编码的 protobuf message。区别不仅是格式——而是编程模型。REST 的接口定义是"约定"(API doc + 样板)。gRPC 的接口定义是编译器验证的合约——改了 .proto,所有调用方必须更新否则编译失败。
tonic 是 Rust 生态中最成熟的 gRPC 实现,基于 tokio + tower + prost (protobuf 编译器)。
从 .proto 到 Rust 类型
syntax = "proto3";
package greeter;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply); // unary: 1 request → 1 response
rpc StreamHello (HelloRequest) returns (stream HelloReply); // server streaming
rpc Chat (stream ChatMessage) returns (stream ChatMessage); // bidi streaming
}
message HelloRequest { string name = 1; }
message HelloReply { string message = 1; }
build.rs 中 tonic_build::compile_protos() 调用 protoc + prost 生成:
GreeterServer<T: Greeter>— server wrapper(把Greetertrait 包装为 towerService)Greetertrait — 业务逻辑的接口(你实现的方法)GreeterClient— client stub(调用方使用的 async 方法)
生成的代码用 #[tonic::async_trait] 实现 trait 方法——这允许 trait 中包含 async fn(原生 Rust trait 尚不支持 async fn)。
Server: 实现 trait
;
builder
.add_service
.serve.await?;
Status 是 gRPC 的标准错误类型——不是 HTTP status code。gRPC 定义了 17 个 status codes:Ok, Cancelled, InvalidArgument, NotFound, AlreadyExists, PermissionDenied, Unauthenticated, ResourceExhausted, Unimplemented, Internal, Unavailable, DeadlineExceeded。每个 code 有明确的语义——不像 HTTP 中 400 可能代表"格式错误"也可能代表"参数缺少"。
Streaming: 不只是"一次请求一次响应"
// Server streaming: server 逐步发送数据
async
// Bidirectional streaming: 双方同时发送
async
streaming 的关键:server streaming = server 返回 stream T,client 逐个接收。bidirectional = 两端各自发送 stream。这与 WebSocket 的"双向通道"不同——gRPC streaming 的每个消息仍是独立的、有类型的 protobuf message。
Interceptor: 请求级别的中间件
builder
.add_service
interceptor 在 handler 之前执行——可以做认证、限流、metadata 注入。与 tower Layer 的区别:interceptor 是 tonic 的专属概念,Layer 是 tower 的通用概念。tonic 的 interceptor 实际上就是 tower Service 的一个薄封装。
参考
- tonic: github.com/hyperium/tonic
- gRPC: grpc.io (spec, status codes)
- protobuf: protobuf.dev (encoding, proto3 language guide)
Keywords: tonic, gRPC, protobuf, streaming, interceptor, Status, unary, bidirectional