1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GraphQL入門-2:REST APIとの比較(1) - 「オーバーフェッチ」問題

Last updated at Posted at 2025-12-01

はじめに

本記事は、自分の備忘録も兼ねて書いてます。

第1回は、GraphQLの概要とREST APIの課題について記載しました。

今回は、APIの課題の1つ「オーバーフェッチ (Over-fetching)」について、なぜ問題となるのか、GraphQLがどのように解決するのかを見ていきます。


【動作環境】

本記事は、第1回で作成したapi.py(Flaskサーバー)が、以下の環境で起動していることを前提とします。

  • サーバー: python api.py を実行し、http://127.0.0.1:5000/ で起動中
  • クライアント: curl コマンドが実行可能なターミナル

「オーバーフェッチ」について

まず、「オーバーフェッチ」とは何か。
これは、APIにデータを要求した際に、クライアント(アプリケーション)が「実際に必要としている情報よりも多くの情報」を受け取ってしまうことです。

1. デモ

以下は、第1回で実行したコマンドです。

  • クライアントの要求: 「IDが1のユーザーの名前(name)だけ」が欲しい
  • 実行コマンド:
    $ curl http://127.0.0.1:5000/users/1
    
  • APIからのレスポンス:
    {
      "address": "東京都...", 
      "email": "taro@example.com", 
      "id": "1", 
      "joined_date": "2023-01-01", 
      "name": "佐藤 太郎"
    }
    

本来、クライアントが欲しかったのは "name": "佐藤 太郎" という情報だけです。
しかし、実際にはaddressemailjoined_dateといった、不要なデータが含まれてしまっています。(オーバーフェッチ)

2. なぜオーバーフェッチが問題なのか

「データの取りすぎ」は、以下のような問題があります。

  • クライアント側の問題:
    不要なデータもネットワークを通じて送受信されるため、通信データ量が増加します。これは、アプリケーションの応答速度低下に繋がります。
  • サーバー側の問題:
    サーバー側も、不要なデータもデータベースから取得し、JSON形式に変換する処理を行っています。これは、データベースやサーバーのCPUリソースの無駄遣いにつながります。

原因分析

この問題は、api.py のコード設計に起因しています。

api.py/users/<user_id> エンドポイント:

@app.route('/users/<user_id>', methods=['GET'])
def get_user(user_id):
    user = users_data.get(user_id)
    if user:
        # 常に「user」オブジェクトの「すべて」を返している。
        return jsonify(user)
    else:
        return jsonify({"error": "User not found"}), 404

この関数は、「user_id に紐づくユーザー情報をすべて返す」ことしかできません。
そのため、クライアント側の「トップページでは名前だけ欲しい」「設定画面では名前とEmailが欲しい」といった、細かい対応ができない設計になっています。


従来のREST APIでの対策

この問題をREST APIで解決しようとすると、管理が難しくなるという問題が発生します。

  • 対策1:専用のエンドポイントを新設

以下のように、「名前だけ返すAPI」を作ったとします。
例)@app.route('/users/<user_id>/name')

しかし、「Emailだけ欲しい」「名前とEmailが欲しい」など、クライアントの要求の組み合わせの数だけ、APIのエンドポイント(URL)が増加し、管理が非常に困難になります。

  • 対策2:クエリパラメータで指定する

GET /users/1?fields=name,email のように、URLの末尾で欲しいフィールドを指定できるようにします。

この場合、get_user 関数の実装が非常に複雑(fieldsパラメータを解析し、userオブジェクトから動的にキーを抜き出す等)になります。これは、REST APIのシンプルな設計思想から外れていきます。

GraphQLによる解決策

GraphQLは、この「クライアントが必要なフィールドだけを指定する」という技術仕様を持っています。

クライアントは、サーバーが固定したURLにアクセスするのではなく、サーバーに対して「このような構造のデータが欲しい」という「クエリ」を送信します。

# クライアントが欲しいデータだけを指定して送信
query {
  user(id: "1") {
    name
  }
}

GraphQLサーバーは、このクエリを受け取ると、userid: "1" のデータのうち、nameフィールドだけを解決する処理(リゾルバ)を実行します。addressemailのリゾルバは呼び出されません。

その結果、サーバーからの応答は、クライアントが要求した通りの最小限のデータになります。

{
  "data": {
    "user": {
      "name": "佐藤 太郎"
    }
  }
}

このように、GraphQLはクライアントが必要なフィールドを「宣言」する仕組みによって、オーバーフェッチの問題を解決します。


まとめ

  • オーバーフェッチは、クライアントが必要としないデータまで取得してしまうことで、通信量の増大やリソースの無駄遣いにつながる
  • REST APIでは、サーバー側が返すデータ構造を固定する設計のため、構造的に、オーバーフェッチが発生しやすい
  • GraphQLは、クライアントが欲しいフィールドを「クエリ」として明示的に宣言することで、この問題を解決する

次回は、「アンダーフェッチ」(データが足りない問題)について記載します。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?