SPAとGraphQLが結びつく理由とOverfetch問題

SPAでは「必要なデータだけ欲しい」ためGraphQLが選ばれやすい

SPAでGraphQLが採用されやすい理由は、流行でも思想でもありません。
SPAのデータ取得モデルが、REST APIよりもGraphQLの方に適合しやすいからです。

そしてその背景にあるのが「Overfetch(オーバーフェッチ)問題」です。

結論から言うと、SPAは「画面の部品ごとにデータを要求するアプリケーション」です。
REST APIは「リソース単位でデータを返す設計」です。
このズレがパフォーマンスと設計の摩擦を生みます。

REST APIは“画面”ではなく“資源”を返す

REST APIはリソース志向です。
典型的なエンドポイントは次のようになります。

  • /users/1
  • /orders/15
  • /products/10

つまり「ユーザー」「注文」「商品」という単位でデータが返ります。

例えばユーザーAPI。

{
  "id": 1,
  "name": "Taro",
  "email": "taro@example.com",
  "address": "Tokyo",
  "phone": "090-xxxx",
  "created_at": "2024-01-01",
  "updated_at": "2024-01-01"
}

しかしSPAの画面では、すべての項目を使うとは限りません。
ヘッダーに表示したいのは「名前」だけ、というケースは非常に多いです。

ここでOverfetchが発生します。

Overfetch問題とは何か

Overfetchとは、必要ないデータまで取得してしまう状態です。

SPAではコンポーネントごとに必要な情報が異なります。

例:

コンポーネント 必要なデータ
ヘッダー ユーザー名
プロフィール 住所・電話
管理画面 全項目

REST APIは同じレスポンスを返すため、ヘッダー表示のためだけに巨大なJSONを受信することになります。
モバイル回線ではこの差が体感速度に直結します。

SPAは“画面中心設計”のアプリケーション

SPAではReactやVueのコンポーネントが単位になります。

<UserName id="1" />

このコンポーネントが必要なのは名前だけです。
しかしRESTではリソース全体が返ります。

つまり、

REST:サーバ中心のデータ構造
SPA:画面中心のデータ要求

この構造差がGraphQLの登場理由です。

GraphQLは「画面が欲しい形でデータを取得する」

GraphQLではクエリで必要項目を指定します。

query {
  user(id: 1) {
    name
  }
}

レスポンス:

{
  "data": {
    "user": {
      "name": "Taro"
    }
  }
}

住所も電話も送られません。
つまりOverfetchが発生しません。

これがSPAでGraphQLが採用されやすい最大の理由です。

Underfetch問題も同時に解決する

RESTでは逆の問題も起きます。
「情報が足りない」問題です。

例:ユーザーと注文履歴を同時表示したい場合

  • /users/1
  • /orders?user_id=1

2回の通信が必要になります。
これをUnderfetchと呼びます。

GraphQLなら1回のリクエストです。

query {
  user(id: 1) {
    name
    orders {
      id
      total
    }
  }
}

SPAではコンポーネントが多いため、この差が非常に大きくなります。

それでもGraphQLが万能ではない理由

GraphQLにも明確なデメリットがあります。
最大の問題はキャッシュです。

RESTはURL単位でキャッシュできます。

  • GET /users/1

一方GraphQLはPOSTで任意クエリを送ります。

POST /graphql

クエリが毎回異なるためCDNキャッシュが効きません。
トラフィックが増えるとサーバ負荷が増大します。

現場で起きる意外な問題

GraphQLを導入すると、フロントエンドがAPI設計を主導します。
その結果、バックエンドの最適化が難しくなります。

例えば次のクエリ。

query {
  users {
    orders {
      items {
        product {
          reviews {
            rating
          }
        }
      }
    }
  }
}

一見便利ですが、内部では膨大なDBアクセスが発生します。
N+1問題が起きやすくなります。

どちらを選ぶべきか

SPAだから必ずGraphQL、というわけではありません。

GraphQLが向くケース

  • 画面ごとに必要データが違う
  • モバイル通信が多い
  • UIが頻繁に変わる

RESTが向くケース

  • シンプルなCRUD
  • キャッシュ重視
  • 公開API

最後に理解しておきたいこと

GraphQLが広まったのは「新しいから」ではありません。
SPAというアーキテクチャが、RESTの前提と合わなくなった結果です。

RESTはサーバ中心設計、
SPAは画面中心設計。

GraphQLはその間を埋めるための「問い合わせ言語」です。

つまりGraphQLはRESTの代替ではなく、
SPAのデータ取得モデルに合わせたAPIの形と捉えると理解しやすくなります。