gRPCの4つの通信方式とREST API比較
gRPCの通信方式(HTTP/2ベース)
1. Unary RPC
code: sh
RESTと同じパターン。
2. Server Streaming RPC
code: sh
3. Client Streaming RPC
code: sh
4. Bidirectional Streaming RPC
code: sh
双方向で任意のタイミングで送受信可能
HTTP/2上のRESTでストリーミングは可能か?
技術的には可能ですが、RESTの設計思想と矛盾
RESTでのストリーミング対応
可能な方式(限定的)
1. Server-Sent Events (SSE)
code:sh
// RESTでサーバーからクライアントへのストリーミング(一方向)
GET /api/events HTTP/1.1
Accept: text/event-stream
// サーバーレスポンス
HTTP/1.1 200 OK
Content-Type: text/event-stream
data: {"message": "イベント1"}
data: {"message": "イベント2"}
data: {"message": "イベント3"}
2. HTTP/2のMultiplexing
code:sh
// 複数のRESTリクエストを並行実行(ただし各々は独立)
GET /api/user/1 HTTP/2
GET /api/posts/recent HTTP/2
GET /api/notifications HTTP/2
// ↑ これらが同一コネクション上で並行処理される
RESTでできないこと
❌ Client Streaming: 複数リクエスト→1レスポンス
❌ Bidirectional Streaming: 双方向任意タイミング通信
❌ 統一されたストリーム制御: gRPCのような整合性
技術的制約の比較
gRPC(HTTP/2専用設計)
code:sh
service ChatService {
// ✅ 4つすべての通信パターン対応
rpc SendMessage(Message) returns (MessageResponse); // Unary
rpc GetMessages(User) returns (stream Message); // Server Streaming
rpc UploadFile(stream FileChunk) returns (UploadResponse); // Client Streaming
rpc Chat(stream Message) returns (stream Message); // Bidirectional
}
REST(HTTP/2上でも制約あり)
code:sh
// ✅ 基本的なリクエスト・レスポンス
GET /api/messages
POST /api/messages
// ⚠️ サーバーストリーミング(SSE使用、制限的)
GET /api/events // text/event-stream
// ❌ クライアントストリーミング(RESTの思想と矛盾)
// ❌ 双方向ストリーミング(RESTの思想と矛盾)
なぜRESTでは制限があるのか
RESTの設計思想
リソース指向: URLがリソースを表す
ステートレス: 各リクエストが独立
統一インターフェース: HTTP動詞(GET、POST等)の標準使用
REST思想: 1つのURL = 1つのリソース = 1つのレスポンス
gRPCストリーミング: 1つのRPC呼び出し = 複数データのストリーム
table: 選択指針
通信パターン REST gRPC
基本的なCRUD ✅ 最適 ✅ 可能
リアルタイム通知 ⚠️ SSE(制限的) ✅ Server Streaming
ファイルアップロード ⚠️ 分割アップロード ✅ Client Streaming
チャット・ゲーム ❌ 困難 ✅ Bidirectional