GraphQL gRPC徹底比較

RESTの次世代を選ぶ「適材適所」のAPI設計論

前回の記事で、我々は「REST API」の理想と現実を解き明かした。多くの現場で使われる「REST API」が、HTTPメソッドとURI(リソース)の原則を採用しつつも、提唱者が目指したHATEOASという理想には至っていない現実を見た。

そして、その現実的なREST(HTTP+JSON API)には、 「N+1問題」「オーバーフェッチ」 といった、クライアント開発(特にモバイル)において深刻なパフォーマンス問題を引き起こす限界があることも指摘した。

このRESTの限界を乗り越えるべく登場したのが、Facebook(現Meta)が生んだ GraphQL と、Googleが生んだ gRPC である。

だが、これら二つの技術を「RESTの次」として単純に比較し、「どちらが優れているか」を競わせるのは危険な誤解を生む。GraphQLが解決しようとした課題と、gRPCが解決しようとした課題は、似ているようで根本的に異なるからだ。

GraphQLは「データ取得の柔軟性」を、gRPCは「通信の絶対速度」を追求した技術である。

本記事の目的は、この二つの技術の設計思想、具体的な仕組み、そして得意分野を徹底的に対比することだ。この記事を読み終えるとき、読者は「いつ、どちらの技術(あるいは引き続きREST)を選ぶべきか」という「適材適所」の判断基準を明確に手に入れているはずである。


1. GraphQL:「クライアントの要求」にすべて応えるクエリ言語

GraphQLは、APIのための「クエリ言語(Query Language)」である。その最大の特徴は、 「必要なデータ構造をクライアント側が定義して要求する」 という点にある。これは、サーバー側が定義したリソース(URI)にアクセスするRESTとは根本的に異なる設計思想だ。

GraphQLが解決する核心的課題

GraphQLが狙い撃ちしたのは、まさしくRESTが抱える以下の問題である。

  • オーバーフェッチ(Over-fetching): 「名前だけ欲しい」のに、RESTの GET /users/123 が住所や電話番号まで返してしまう問題。
  • アンダーフェッチ(Under-fetching): 1つの画面(例:ユーザー情報+最新投稿3件)を表示するために、GET /users/123GET /users/123/posts のように複数回のAPIリクエストが必要になる問題。これはN+1問題の温床でもある。

これらの問題は、クライアント(特に通信環境が不安定なモバイルアプリ)の表示速度やUX(ユーザー体験)を著しく低下させる。

GraphQLの仕組み:要求した通りのデータが返る

GraphQLでは、クライアントは「このような構造のJSONが欲しい」というクエリをサーバー(通常は単一のエンドポイント、例: /graphql)にPOSTで送信する。

例:RESTとGraphQLの対比

ある画面で「ID:123のユーザー名」と「そのユーザーの最新投稿2件のタイトル」が必要だとする。

RESTの場合(アンダーフェッチ発生)

  • Request 1: GET /users/123
    • Response: {"id": 123, "name": "Yamada", "age": 30, "address": "...", ...}
    • クライアントは “name” 以外を捨てる(オーバーフェッチ)
  • Request 2: GET /users/123/posts?limit=2
    • Response: [{"id": 501, "title": "First post", "body": "..."}, {"id": 502, "title": "Second post", "body": "..."}]
    • クライアントは “title” 以外を捨てる(オーバーフェッチ)

このように、2回のリクエストと、大量の不要データ(オーバーフェッチ)が発生する。

GraphQLの場合(1リクエストで解決)

  • Request: POST /graphql
    • Query (Body):
      query {
        user(id: "123") {
          name
          posts(limit: 2) {
            title
          }
        }
      }
  • Response:
    {
      "data": {
        "user": {
          "name": "Yamada",
          "posts": [
            { "title": "First post" },
            { "title": "Second post" }
          ]
        }
      }
    }

たった1回のリクエストで、クライアントが要求した構造(namepoststitle)通りのデータが、過不足なく返却される。オーバーフェッチもアンダーフェッチも存在しない。

GraphQLの主戦場とトレードオフ

この特性から、GraphQLの主戦場は明確である。

  • 主戦場: クライアント-サーバー間通信
    • 特に、Webフロントエンドやモバイルアプリなど、多様な画面構成やデータ要求が頻繁に変わる場所。
    • BFF (Backends For Frontends) パターン、すなわちフロントエンドごとに最適化されたAPI層として絶大な効果を発揮する。

ただし、GraphQLには強力な反面、考慮すべきトレードオフが存在する。

  • サーバー側の複雑性: サーバーはクライアントのどんなクエリにも応えられるよう、データの関連性を解決するロジック(リゾルバ (Resolver) と呼ばれる)を細かく実装する必要があり、RESTより複雑になる。
  • キャッシュ戦略: RESTのようにURIごと(GET /users/123)にHTTPキャッシュ(CDNなど)を効かせるのが難しくなる(すべて POST /graphql になるため)。
  • クエリの暴走: クライアントが過度にネストした複雑なクエリ(例:ユーザーの友達の友達の投稿一覧…)を投げると、サーバーに過負荷がかかる危険性がある(対策は可能)。

2. gRPC:「サーバー間の速度」を極限まで追求するRPC

gRPCは、Googleが開発したオープンソースの「RPC (Remote Procedure Call)」フレームワークである。RPCとは、日本語で「遠隔手続き呼出」と言い、まるでローカルにある関数(手続き)を呼び出すかのように、ネットワーク越しに別サーバーの機能を呼び出す仕組みを指す。

gRPCは「RESTの限界」を解決するために生まれたが、GraphQLとは全く異なるアプローチを取った。gRPCが着目したのは、 「通信の絶対速度」 である。

gRPCが解決する核心的課題

gRPCが狙い撃ちしたのは、RESTが前提とする「HTTP/1.1」と「JSON」が持つ、通信効率の悪さである。

  • HTTP/1.1のオーバーヘッド: リクエストごとに接続を確立し直す(あるいは接続数に限りがある)ため、非効率。
  • JSONの冗長性: JSONは人間が読めるテキスト形式であり、非常に便利だが、バイナリ形式に比べてデータサイズが大きく、解析(パース)にも時間がかかる。

これらの問題は、クライアント-サーバー間でも影響するが、それ以上に、システム内部でサーバー同士が1秒間に何千回、何万回と通信し合う「マイクロサービス」環境において致命的なボトルネックとなる。

gRPCの仕組み:HTTP/2とProtobufによる高速化

gRPCは、速度を追求するために2つの強力な技術を土台としている。

  1. HTTP/2: HTTP/1.1の欠点を根本的に改善したプロトコル。gRPCはHTTP/2を必須とする。
    • 単一接続の多重化: 1つのTCP接続内で複数のリクエスト/レスポンスを並行して双方向にやり取りできる(ストリーミング)。これにより、接続のオーバーヘッドが劇的に減少する。
  2. Protocol Buffers (Protobuf): gRPCの標準データ形式(シリアライズ形式)。JSONやXMLの代わりに使われる。
    • 高速なバイナリ形式: テキストではなくコンパクトなバイナリ形式でデータを送受信するため、データ量が小さく、JSONの何倍も高速にシリアライズ・デシリアライズ(解析)できる。
    • 厳格なスキーマ定義: .proto という専用ファイルでAPIの仕様(関数やデータ構造)を厳密に定義する。このファイルから各言語(Go, Java, Python, Node.jsなど)のコードが自動生成されるため、サーバーとクライアント間の型が保証される。

gRPCの主戦場とトレードオフ

この「圧倒的な速度」と「厳格な型定義」から、gRPCの主戦場もまた明確である。

  • 主戦場: サーバー間通信(内部バックエンド)。
    • マイクロサービス間の通信。
    • 低遅延(ローレイテンシ)と高スループット(大量処理)が最優先される内部API。

gRPCもまた、その速度と引き換えにトレードオフを抱えている。

  • 人間の可読性の欠如: データがバイナリ形式であるため、curl コマンドでJSONのように中身を覗いたり、デバッグしたりするのが難しい(専用ツールが必要)。
  • ブラウザの非互換性: ブラウザ(JavaScript)は標準でgRPCを直接サポートしていない。ブラウザから利用するには、gRPC-Webというプロキシ(仲介役)を別途立てる必要がある。
  • 厳格なスキーマ: .proto ファイルによる厳格な定義は、裏を返せば「ちょっと試してみる」という気軽な開発には向かず、スキーマの変更管理コストが発生する。

3. 徹底比較:REST vs GraphQL vs gRPC

ここで、3つの技術特性を整理し、その違いを明確にする。

比較軸 REST (現実のAPI) GraphQL gRPC
主な用途 公開API、シンプルなCRUD クライアント-サーバー間 サーバー間 (マイクロサービス)
通信プロトコル HTTP/1.1 (または2) HTTP/1.1 (または2) HTTP/2 (必須)
データ形式 JSON JSON Protocol Buffers (バイナリ)
設計思想 リソース指向 クエリ指向 (クライアント中心) サービス指向 (RPC)
N+1問題 発生しやすい 根本的に解決する 発生しない (用途が異なる)
オーバーフェッチ 発生しやすい 根本的に解決する 発生しない (スキーマで定義)
スキーマ定義 OpenAPI (任意) スキーマ定義 (必須) .proto ファイル (必須)
強み シンプルさ、普及率、キャッシュ データ取得の圧倒的柔軟性 圧倒的な通信速度、厳格な型
弱み N+1問題、オーバーフェッチ キャッシュが難しい、実装複雑性 人間の可読性、ブラウザ非互換

考察:競合ではなく「共存」するアーキテクチャ

「GraphQL vs gRPC」という対立構造で語られることが多いが、本記事の比較(特に「主な用途」)を見れば明らかな通り、その構図は多くの場合、誤りである。両者は得意分野が全く異なる

現代の複雑なWebサービスにおいて、これらは競合するどころか、むしろ「共存」することで最強のアーキテクチャを形成する。

典型的な共存モデルは以下のようになる。

[クライアント (Web/Mobile)] $\downarrow$ (GraphQL) $\leftarrow$ データ取得の柔軟性が最重要 $\downarrow$ [BFF / API Gateway] $\downarrow$ (gRPC) $\leftarrow$ 内部通信の速度が最重要 $\downarrow$ [内部マイクロサービス A] $\leftarrow (gRPC) \rightarrow$ [内部マイクロサービス B]

この構成では、以下の利点を両取りできる。

  1. 外部(クライアント-BFF間): GraphQL を採用する。
    • クライアントは、N+1問題やオーバーフェッチに悩まされることなく、必要なデータだけを1回のリクエストで柔軟に取得できる。
  2. 内部(BFF-サービス間、サービス-サービス間): gRPC を採用する。
    • BFFはクライアントからのGraphQLリクエストを受け取り、それを解釈して、内部の複数のマイクロサービス(例:ユーザーサービス、投稿サービス)をgRPCで高速に呼び出す。
    • マイクロサービス間の通信も全てgRPCで行うことで、システム全体の遅延を最小限に抑える。

もちろん、システムがシンプルであったり、広く一般に公開するAPIであったりするならば、普及率とシンプルさ、キャッシュの容易さにおいて、今でもRESTが最適解であるケースは多い。


まとめ

この記事では、RESTの次世代API技術として注目されるGraphQLとgRPCを徹底的に比較した。

  • GraphQLは「データ取得の柔軟性」を追求し、クライアント-サーバー間の通信(特にN+1問題やオーバーフェッチ)を劇的に効率化する。主戦場はBFFやモバイルアプリのバックエンドだ。
  • gRPCは「通信の絶対速度」を追求し、HTTP/2とバイナリ形式(Protobuf)によってサーバー間の通信を圧倒的に高速化する。主戦場はマイクロサービスの内部通信だ。

最終的に重要なのは、流行の技術に飛びつくことでも、一つの技術に固執することでもない。それぞれの設計思想が「何を解決するために生まれたのか」という本質と、その「トレードオフ」を正確に理解することである。

REST、GraphQL、gRPCは、競合する敵同士ではない。我々の道具箱(ツールボックス)に収められた、それぞれに得意な用途を持つ「異なる道具」に過ぎないのだ。構築すべきシステムの要件に対し、最適な道具を選択する眼を持つことこそが、現代の設計者には求められている。