このページの目次
tonic (gRPC)
gRPC は protobuf を用いて強型付けされたサービスインターフェースを定義する——.proto を変更すると、呼び出し元はすべて更新しなければならない。さもないとコンパイルエラーになる(規約ではなく、コンパイラで検証される契約)。tonic は Rust 用の gRPC 実装であり、codegen は .proto から Rust の trait やストリーミング型(unary/client/server/bidi)を生成し、interceptor 層は異なるユースケースや横断的ロジックに対応する。
gRPC と REST の違い
REST は HTTP メソッドと URL を用いて操作を表現し、ペイロードは通常 JSON です。gRPC は protobuf を用いて強型付けされたサービスインターフェースを定義し、ペイロードはバイナリエンコードされた protobuf メッセージです。違いはフォーマットだけでなく、プログラミングモデルにあります。REST のインターフェース定義は「規約」(API ドキュメント + 定型コード)です。gRPC のインターフェース定義はコンパイラで検証される契約——.proto を変更すると、呼び出し元はすべて更新しなければならない。さもないとコンパイルエラーになります。
tonic は Rust エコシステムで最も成熟した gRPC 実装であり、tokio + tower + prost (protobuf コンパイラ) を基盤としています。
.proto から Rust 型へ
syntax = "proto3";
package greeter;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply); // unary: 1 リクエスト → 1 レスポンス
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>— サーバーラッパー(Greetertrait を towerServiceにラップ)Greetertrait — ビジネスロジックのインターフェース(あなたが実装するメソッド)GreeterClient— クライアントスタブ(呼び出し側が使用する非同期メソッド)
生成されたコードは #[tonic::async_trait] を用いて trait メソッドを実装しています。これは、trait 内に async fn を含めることを可能にします(Rust のネイティブな trait はまだ async fn をサポートしていません)。
サーバー: trait の実装
;
builder
.add_service
.serve.await?;
Status は gRPC の標準エラー型です——HTTP ステータスコードではありません。gRPC は 17 種類のステータスコードを定義しています:Ok, Cancelled, InvalidArgument, NotFound, AlreadyExists, PermissionDenied, Unauthenticated, ResourceExhausted, Unimplemented, Internal, Unavailable, DeadlineExceeded。各コードには明確なセマンティクスがあり、HTTP の 400 が「フォーマットエラー」也可能是「パラメータ不足」を表すのとは異なります。
ストリーミング: 「1 リクエスト 1 レスポンス」だけではない
// Server streaming: サーバーが段階的にデータを送信
async
// Bidirectional streaming: 両側が同時に送信
async
ストリーミングの鍵:server streaming = サーバーが stream T を返し、クライアントが逐次受信する。bidirectional = 両側がそれぞれ stream を送信する。これは WebSocket の「双方向チャネル」とは異なります——gRPC ストリーミングの各メッセージは依然として独立した、型付きの protobuf メッセージです。
Interceptor: リクエストレベルのミドルウェア
builder
.add_service
interceptor はハンドラーの前に実行されます——認証、レート制限、メタデータの注入などが可能です。tower Layer との違い:interceptor は tonic 固有の概念であり、Layer は tower の汎用概念です。tonic の interceptor は実際には tower Service の薄いラッパーです。
参考
- tonic: github.com/hyperium/tonic
- gRPC: grpc.io (仕様、ステータスコード)
- protobuf: protobuf.dev (エンコーディング、proto3 言語ガイド)
Keywords: tonic, gRPC, protobuf, streaming, interceptor, Status, unary, bidirectional