Rundevlog

小さい会社のしがないエンジニアのブログ

2025.3.23

GraphQL概論

API設計まわりを触っていて、GraphQLとSubscriptionの理解があいまいだったので調べた内容を整理。
REST APIとの比較や、Subscriptionの流れ・スキーマ構造なんかもまとめておく。

GraphQLとは何か

GraphQLは、1つのエンドポイントで必要なデータだけを柔軟に取得できるAPI設計のための技術。
RESTのように「リソースごとにエンドポイントを分ける」方式とは異なり、クライアント側で欲しいデータをピンポイントに指定して取得できる。

RESTだと、例えば「ユーザーの基本情報と投稿一覧を同時に取得したい」みたいな場面で、複数エンドポイントにリクエストを投げる必要が出てくる。
それに対してGraphQLなら、1リクエストで必要な情報を全部引っ張ってくることが可能。

特徴

  • エンドポイントは基本的に1つ
  • データの取得単位をクライアント側で細かく指定できる
  • 過不足ないレスポンスが得られる
  • サーバーサイドの実装が比較的軽くなる

クライアント側が「この形式で、このフィールドだけくれ」と指定してリクエストする設計になっている。
この仕様は「スキーマ」と呼ばれる定義ファイルに基づいていて、APIのインターフェースをあらかじめ明示的に定義しておく仕組み。

RESTとの違い(ざっくり)

比較項目RESTGraphQL
エンドポイントリソースごとに分かれる基本1つだけ
データ取得方法決まった構造で固定欲しいフィールドを選んでリクエスト可能
データの過不足起こりがち(過剰 or 不足)必要な分だけ取得できる
クライアント主導△(柔軟性は低い)◎(かなり柔軟)

GraphQLで使われる用語

  • Query:データの取得(DB検索に相当)
  • Mutation:データの作成・更新・削除
  • Subscription:データの変更をリアルタイムで監視して通知(WebSocket使用)
  • Schema:GraphQL APIの仕様定義(型、安全性、入力値の構造など)
  • Resolver:実際のデータ取得や操作を担当する関数(QueryやMutationの中身)

WebSocketとリアルタイム通信

GraphQLのSubscriptionはWebSocketを使った仕組み。
WebSocketは、HTTPのように「リクエストに対するレスポンス」という流れじゃなく、サーバーからクライアントへプッシュ通知が可能なプロトコル。

通常のHTTP通信だと、クライアントがリクエストしない限りデータは返ってこない。
これだとリアルタイムな通知には向いていない。
WebSocketを使えば、サーバー側から「データ変わったよ」と即座に通知を送ることができる。

GraphQLではこのWebSocketを活用して、Subscriptionによるリアルタイム更新を実現している。

Subscriptionの処理の流れ

たとえばチャットアプリなどで新しいメッセージを即座に受け取る仕組みを作る場合、GraphQLのSubscriptionを使うことになる。

処理の流れ(ざっくり)

  1. クライアントがSubscriptionを開始
    WebSocketでGraphQLサーバーと接続し、「このmutationが発生したら通知してほしい」という設定を送る。
  2. 別のクライアントがMutationを実行
    例えばClient Bがメッセージを投稿(=createMessage mutationを実行)
  3. サーバーが更新を検知して通知
    Client Aはあらかじめサブスクライブしていたため、更新内容の通知を受け取る。
  4. 通知を受けて再度Queryでデータを取得
    受け取った通知に応じて、定義しておいたQueryを使い、必要なデータを取得。

スキーマとSubscriptionの対応関係

GraphQLでは、Subscriptionもスキーマに明示的に定義する。

graphqlコピーする編集するtype Subscription {
  onCreateMessage(roomId: ID!): Message
    @aws_subscribe(mutations: ["createMessage"])
}

この定義を分解すると:

  • onCreateMessage:サブスクリプション関数の名前(クライアントが呼び出す)
  • roomId: ID!:引数(どのルームの更新を監視するか)
  • Message:戻り値の型(通知時に取得するデータ)
  • @aws_subscribe(mutations: ["createMessage"]):どのmutationがトリガーになるかの指定

このスキーマに基づいて、クライアント側は以下のような動作をする:

  1. onCreateMessage(roomId: 123)をサブスクライブ(クライアントA)
  2. createMessage(roomId: 123)が別クライアントBから実行される
  3. サーバーがサブスクリプションを発火、クライアントAに通知
  4. クライアントAは通知を受け取り、必要なデータを取得して画面に反映

まとめ

GraphQLの基本を押さえるなら、以下の3点をまず理解するとよさそう:

  • Query:データ取得
  • Mutation:データ操作(作成・更新・削除)
  • Subscription:リアルタイム通知(WebSocketで動作)

RESTでは複数エンドポイントを組み合わせてデータ取得していた部分を、GraphQLでは1リクエストで柔軟に処理できる。
さらにWebSocketによるリアルタイム対応ができるのもGraphQLの大きな強み。

チャットや通知系の機能を作るなら、Subscriptionまわりをちゃんと把握しておくとかなり役立つ。