【比較】REST・gRPC・WebSocketの違い¶
概要¶
REST・gRPC・WebSocket は、サービス間で通信する際の通信モデル(やり取りの形)・トランスポート・契約(スキーマ)の取り方が根本的に異なります。REST は HTTP 上のリクエスト/レスポンス型でリソース指向、gRPC は HTTP/2 上の RPC(リモートのメソッドをローカル呼び出しのように呼ぶ)で Protocol Buffers による契約とストリーミングを持ち、WebSocket は1本の TCP コネクション上で全二重(双方向)の持続通信を行うプロトコルです。
この記事は当サイトの「RESTとGraphQL」とは観点が異なり、補完関係にあります。あちらは「クライアントが必要なデータを柔軟に指定できるか(オーバーフェッチ/アンダーフェッチ)」というクエリ表現力の軸の比較です。本記事は トランスポート(何の上を流れるか)・ストリーミング(一方向か双方向か持続接続か)・契約(型・スキーマの強制度) の軸で REST/gRPC/WebSocket を比較します。重なる話を蒸し返さず、別の切り口として読んでください。
例えるなら:やり取りの「形」の違い¶
- REST … 窓口に申請書を出して回答を受け取る。1往復で完結。次の用があればまた窓口へ並ぶ(リクエスト/レスポンス)。
- gRPC … 専用の内線電話で「この関数を実行して」と頼むと結果が返る。事前に交わした業務マニュアル(.proto 契約)通りにしか話せず、必要なら回線を開いたまま連続報告(ストリーミング)もできる。
- WebSocket … 双方が受話器を上げっぱなしの通話。どちらからでも好きなタイミングで話せる(全二重・持続接続)。何を話すかの取り決めは利用者側で決める。
詳細比較¶
| 比較軸 | REST | gRPC | WebSocket |
|---|---|---|---|
| 通信モデル | リクエスト/レスポンス(リソース指向) | RPC(遠隔メソッド呼び出し) | 全二重の双方向メッセージ |
| トランスポート | HTTP(1.1/2 など) | HTTP/2 上(仕様で HTTP2 framing にマッピング) | HTTP の Upgrade で確立後、単一 TCP 上の独自フレーミング |
| 接続の持続性 | 基本は都度(ステートレス志向) | コール単位、ストリームは接続を開いたまま継続 | 接続を張りっぱなしで維持 |
| ストリーミング | 標準では非対応(基本は1往復) | 単方向×2+双方向=4種(unary/server/client/bidirectional streaming) | 双方向ストリームが本質(どちらからも随時送信可) |
| 契約(スキーマ) | 任意(OpenAPI 等は別途。強制ではない) | 必須:.proto(Protocol Buffers)が IDL 兼シリアライズ形式 |
プロトコル自体は規定せず、アプリ側で定義 |
| ペイロード形式 | 主にテキスト(JSON 等、人間可読) | バイナリ(Protocol Buffers、構造化データを raw bytes に直列化) | テキスト/バイナリ両対応のフレーム |
| ブラウザからの直接利用 | 容易(fetch 等) | 制限あり(ブラウザは gRPC-Web 等を要する) | 容易(標準 WebSocket API) |
| 代表的な用途 | 公開 Web API、CRUD、リソース操作 | 内部マイクロサービス間、低遅延 RPC、ストリーミング | チャット、通知、ライブ更新など双方向リアルタイム |
よくある誤解¶
- 誤解1:「gRPC は REST の新しい書き方で、本質は同じ HTTP API」 — 誤りです。REST は HTTP の上に乗るリソース指向のリクエスト/レスポンス様式ですが、gRPC は「離れたサーバーのメソッドをローカルオブジェクトのように直接呼ぶ」RPCで、公式は「a client application can directly call a method on a server application on a different machine as if it were a local object」と定義します。さらに gRPC は HTTP/2 framing にマッピングされることが公式トランスポート仕様で規定され、契約は
.proto(Protocol Buffers)で強制されます。設計思想が別物です。 - 誤解2:「WebSocket は HTTP の一種/HTTP の上で動き続ける」 — 不正確です。WebSocket は HTTP の Upgrade ハンドシェイクで接続を開始しますが、その後は HTTP ではなく、RFC 6455 が定める独自のフレーミングを単一 TCP 上で用いる別プロトコルへ切り替わります。ハンドシェイクが HTTP として解釈できるのは、既存の HTTP サーバーとポートを共有できるようにするための設計です。
- 誤解3:「リアルタイムが必要なら必ず WebSocket」 — 必ずしもそうではありません。サーバーからクライアントへ一方向に流すだけなら gRPC の server streaming や SSE でも実現できます。WebSocket が本質的に必要なのは双方向(どちらからでも随時送信したい)持続通信のケースです。RFC 6455 自身、WebSocket は「複数の HTTP 接続(XMLHttpRequest や long polling 等)に頼らずに双方向通信する」ために設計されたと述べています。
- 誤解4:「gRPC はストリーミング専用」 — 誤りです。gRPC の最も基本的な呼び出しは unary RPC(1リクエスト→1レスポンス)で「just like a normal function call」と公式が説明しています。ストリーミングは server/client/bidirectional の3種が追加で用意されているだけで、多くの実用 API は unary です。
- 誤解5:「REST より gRPC の方が速いから常に gRPC を選ぶべき」 — トレードオフを無視しています。gRPC はバイナリ(Protobuf)+HTTP/2 多重化で効率的ですが、ブラウザから直接呼びにくい(gRPC-Web 等が必要)、人間可読でなくデバッグしにくい、契約(.proto)の運用が要る、といったコストがあります。公開 Web API では REST + JSON の方が適することが多い。
実務での選び分け¶
3者は競合というより用途で住み分けるものです。
- 公開 Web API・CRUD・ブラウザや多様なクライアントから叩く → REST。HTTP 標準・JSON で相互運用性が高く、キャッシュやデバッグも容易。
- 社内マイクロサービス間の低遅延・型安全な呼び出し、ストリーミングが要る → gRPC。
.protoでスキーマと型を強制でき、HTTP/2 多重化と4種の呼び出しモデル(unary+3ストリーミング)が活きる。 - チャット・通知・共同編集・ライブダッシュボードなど双方向リアルタイム → WebSocket。サーバー/クライアントどちらからも随時メッセージを送れる持続接続が要件にはまる。
- 「サーバー→クライアント一方向の更新通知」だけ → WebSocket でなくても、gRPC server streaming や SSE で足りることが多い。双方向が不要なら無理に WebSocket を選ばない。
- 判断軸:①通信モデル(1往復で済むか/RPC か/双方向持続か) ②契約の強制度(自由か、
.protoで型を強制したいか) ③クライアント(ブラウザ含む広範な相互運用か、内部限定か) ④ペイロード(人間可読 JSON か、バイナリ効率か)。
ひとことまとめ¶
REST=HTTP 上のリクエスト/レスポンス(リソース指向・契約は任意)、gRPC=HTTP/2 上の RPC(Protobuf 契約必須・4種の呼び出しでストリーミング可)、WebSocket=HTTP Upgrade 後に単一 TCP 上で全二重の持続通信。クエリ表現力を論じる REST vs GraphQL とは別軸で、トランスポート・ストリーミング・契約で選び分けます。
出典・参考¶
- gRPC 公式「Introduction to gRPC」(クライアントが別マシンのサーバーのメソッドをローカルオブジェクトのように直接呼べる RPC。既定で Protocol Buffers を IDL 兼シリアライズ形式に用い、
.protoから client/server コードを生成、構造化データをバイナリに直列化): https://grpc.io/docs/what-is-grpc/introduction/ - gRPC 公式「Core concepts, architecture and lifecycle」(4種の RPC:unary=1要求/1応答、server streaming、client streaming、bidirectional streaming=双方向独立ストリーム): https://grpc.io/docs/what-is-grpc/core-concepts/
- gRPC 公式トランスポート仕様「gRPC over HTTP2」(gRPC を HTTP2 framing にマッピングして実装する詳細仕様。RPC を HTTP/2 ストリームに対応づけ、メッセージを DATA フレームで送る): https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md
- RFC 6455「The WebSocket Protocol」(双方向通信を可能にするプロトコル。オープニングハンドシェイク+基本的なメッセージフレーミングを TCP の上に重ねる。複数 HTTP 接続/long polling に頼らず双方向通信するために設計。ハンドシェイクは HTTP Upgrade として解釈でき既存 HTTP サーバーとポート共有可能): https://www.rfc-editor.org/rfc/rfc6455.html
- 当サイト「RESTとGraphQLの違い」(本記事と補完関係:クエリ表現力/オーバーフェッチ・アンダーフェッチの軸の比較)