0Pricing
PHP Academy · レッスン

GraphQLとRESTの比較

どのような場合にGraphQLがRESTより優れているのか、その理由を理解します。

「GraphQLとRESTの比較」はCoddyKit上の無料PHP Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPHP Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 PHP Academyコースには全4レッスンが含まれています。

なぜGraphQLなのか

PHPでREST APIをリリースする方法は、すでにご存じでしょう。GraphQLはHTTPの置き換えでも万能薬でもありません。クライアントが必要なものを正確に記述し、1回の往復でその内容だけを取得できるクエリ言語兼型システムです。

このレッスンでは、両者を率直に比較します。GraphQLが本当に優れている場面、RESTを選ぶべき場面、そしてGraphQLが運用面で課すコストを扱います。

過剰取得と不足取得

RESTでよくある問題は次のとおりです。

  • 過剰取得:GET /users/1が40個のフィールドを返すのに、UIが必要とするのは3個だけです。
  • 不足取得:ユーザーの投稿と各投稿のコメント数を表示するために、/users/1、次に/users/1/posts、さらにN個のコメントエンドポイントを呼び出します。

GraphQLなら、これを1つの宣言的なリクエストにまとめられます。

query {
  user(id: 1) {
    name
    posts {
      title
      commentCount
    }
  }
}

単一エンドポイントと型付きスキーマ

RESTが多数のURLを公開するのに対し、GraphQLは強く型付けされたスキーマに基づく単一のエンドポイント(通常はPOST /graphql)を公開します。スキーマが契約となり、イントロスペクションも可能なので、ツール(自動補完、ドキュメント、コード生成)をすぐに利用できます。

以下はSDLで記述した最小限のスキーマです。考えられるすべてのレスポンスの形を、あらかじめ把握できます。

type User {
  id: ID!
  name: String!
  posts: [Post!]!
}

type Post {
  id: ID!
  title: String!
  commentCount: Int!
}

type Query {
  user(id: ID!): User
}

レスポンスはクエリを反映する

重要な特徴は、JSONレスポンスの形をクエリから予測できることです。クライアントがフィールド名を推測する必要はありません。これにより、バージョン管理に伴う変更の負担を大きく減らせます。既存のクライアントを壊さずにフィールドを追加でき、/v2のURLを新設する代わりに@deprecatedでフィールドを非推奨にできます。

{
  "data": {
    "user": {
      "name": "Ada",
      "posts": [
        { "title": "On Engines", "commentCount": 12 }
      ]
    }
  }
}

GraphQLがRESTに勝る場面

次のような場合は、GraphQLがより適した選択肢です。

  • データのニーズが異なる多様なクライアント(Web、iOS、Android)に対応する場合。
  • データがグラフ構造になっており、クライアントが深い関連を動的にたどる場合。
  • 型付きのゲートウェイの背後に複数のバックエンドを集約したい場合。
  • フロントエンドを素早く反復することが重要で、バックエンドのエンドポイントを何度も変更する状況を避けたい場合。

RESTが今なお優位な場面

反射的にGraphQLを選ばないでください。次のような場合は、RESTのほうがシンプルで適していることがよくあります。

  • HTTPキャッシュが必要な場合 — CDN/エッジキャッシュはURLとHTTPメソッドをキーにするため、単一のPOST /graphqlはキャッシュ側からは内容を判別できません。
  • APIがリソース指向で安定している場合(少数のエンティティに対するCRUD)。
  • ファイルのアップロード/ダウンロードやストリーミングに依存する場合。RESTではmultipartやバイト範囲が第一級の機能として扱われます。
  • 利用者が、標準的なRESTのセマンティクスを期待するサードパーティである場合。

PHPでの簡単な比較

こちらは、REST方式でPHPを使って同じデータを組み立てた例です。クライアントは依然として複数回呼び出すか、embedパラメータを手作業で組み立てる必要がある点に注目してください。一方、GraphQLではその選択ロジックをクライアント側に移します。

<?php
// REST: server decides the payload shape
function userResource(int $id): array {
    return [
        'id' => $id,
        'name' => 'Ada',
        'email' => 'ada@example.com',   // over-fetched by mobile
        'createdAt' => '1815-12-10',
        'posts' => [                       // pre-embedded, all-or-nothing
            ['title' => 'On Engines', 'commentCount' => 12],
        ],
    ];
}

header('Content-Type: application/json');
echo json_encode(userResource(1), JSON_PRETTY_PRINT);

GraphQLがもたらすコスト

GraphQLでは複雑さがサーバー側に移ります。新たに次のような問題を管理する必要があります。

  • N+1クエリ — ネストしたリゾルバーは、バッチ処理(DataLoader)を行わない限り、ノードごとにDBクエリを1回ずつ発行します。
  • クエリコスト/深さの制限 — 悪意のある深くネストされたクエリによって、DoS攻撃を受ける可能性があります。
  • キャッシュが難しくなります。通常はHTTPレイヤーではなく、リゾルバー/データレイヤーでキャッシュします。
  • エラーハンドリングも異なります。200 OKであっても、errors配列を含む場合があります。

エラー:errors配列を伴う200

RESTのステータスコードとは異なり、GraphQLでは慣例的にHTTP 200を返し、部分的な失敗を本文内で報告します。dataには一部のデータだけが設定され、errorsには失敗した内容が列挙されることがあります。クライアントでは両方を確認する必要があります。

{
  "data": { "user": null },
  "errors": [
    {
      "message": "User not found",
      "path": ["user"],
      "extensions": { "code": "NOT_FOUND" }
    }
  ]
}

判断の目安

実用的な判断の目安は次のとおりです。

  • 公開され、キャッシュを多用し、リソースに対するCRUDを行うAPI → REST。
  • 接続されたデータを扱い、多様でリッチなクライアントにデータを提供する内部/プロダクトAPI → GraphQL。
  • 複数のバックエンドを1つの型付きコントラクトの背後に統合する場合 → GraphQLゲートウェイ。

RESTをWebhookやアップロードに、GraphQLをアプリの読み取りグラフに使うなど、両方を併用するのは一般的で健全な構成です。

PHPでHTTP経由のGraphQLを提供する

運用面では、PHPのGraphQLエンドポイントは、JSON本文を読み取り、queryとvariablesを取り出し、スキーマに対して実行して、{ data, errors }を返す1つのルートです。RESTの多数のルートと比べて、通信方式は統一されています。変化する部分はすべて、クライアントが送信するクエリ文字列に含まれます。

<?php
// Minimal GraphQL-over-HTTP entry point
$input = json_decode(file_get_contents('php://input'), true) ?? [];
$query = $input['query'] ?? '';
$variables = $input['variables'] ?? null;

// $result = GraphQL::executeQuery($schema, $query, null, $ctx, $variables);
// header('Content-Type: application/json');
// echo json_encode($result->toArray());
var_dump(['query' => $query, 'variables' => $variables]);

理解度チェック

RESTがGraphQLに対して明確な優位性を保つのは、どのような場合ですか?

まとめ

GraphQLとRESTを本質的な観点から比較しました。

  • GraphQLは、1つの型付きエンドポイントとクライアント主導の選択によって、過剰取得や過少取得を解消します。
  • 多くのクライアント、グラフ状のデータ、バックエンドの集約を扱う場合に優れています。
  • キャッシュ可能な公開API、単純なCRUD、アップロード、標準的な利用者に対しては、RESTが強みを保ちます。
  • GraphQLでは、N+1、クエリコストの制限、キャッシュ、200とerrorsを組み合わせたセマンティクスといったコストがサーバー側に移ります。

次は、webonyx/graphql-phpを使って実際にスキーマを構築します。

よくある質問

「GraphQLとRESTの比較」レッスンは無料ですか?

はい。「GraphQLとRESTの比較」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、PHP Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 PHP Academyコースには全4レッスンが含まれています。

「GraphQLとRESTの比較」で何を学びますか?

どのような場合にGraphQLがRESTより優れているのか、その理由を理解します。 ブラウザで直接実行するハンズオンコードでPHP Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

PHP Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPHP Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「GraphQLとRESTの比較」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPHP Academyレッスンでコードを書いて実行できますか?

はい。すべてのPHP Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. GraphQLとRESTの比較
  2. graphql-phpでスキーマを構築する
  3. リゾルバー、ミューテーション、サブスクリプション
  4. パフォーマンス:N+1とDataLoader
← PHP Academyに戻る