1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

REST APIとGraphQLの併用 ~WEBアプリにおける最適なAPI設計と活用の可能性~

Last updated at Posted at 2025-03-20

1. はじめに

近年、多くのWebアプリケーションでは REST API が広く採用されています。RESTは、シンプルな設計とHTTPプロトコルを活用した柔軟な通信が特徴であり、企業システムやSaaSなどのバックエンドAPIとして広く普及しています。特に、バックエンドをSpring Bootなどのフレームワークで開発し、フロントエンドをSPA(Single Page Application)で構築するケースでは、REST APIが標準的な選択肢となっています。

筆者自身も業務アプリケーションの開発経験が多く、これまで主にシンプルなCRUDを中心としたREST APIの開発を行ってきました。実際、多くのシステムではREST APIで十分な対応が可能ですが、ダッシュボードのように複雑なデータ取得やリアルタイム取得を必要とするケースも一部存在します。このような場合に、GraphQLを活用できる可能性があるのではと考え、少し調べてみました。

REST APIでは、以下のような課題に直面する可能性があります。

  • オーバーフェッチ(不要なデータの取得)
  • アンダーフェッチ(必要なデータが足りない)
  • 複数のAPI呼び出しが必要になるデータ構造
  • リアルタイムデータの取得が困難

もちろん、これらの課題に対してもREST APIの設計次第で対応可能なことが多いですが、一部のケースではGraphQLが有効な選択肢となるかもしれません。そこで、本記事ではREST APIを基本としつつ、GraphQLを併用することで管理画面のデータ取得を最適化する可能性について考察します。

なお、gRPCWebSocketの通信プロトコルを用いたAPI通信技術も存在しますが、本記事ではREST APIとGraphQLに焦点を当てるため、これらについての詳細な説明は割愛します。(まとめにてREST API,GraphQL,gRPC,WebSocketの機能比較表を載せています)


2. REST APIのメリットと課題

2.1 REST APIのメリット

1. シンプルな設計

REST APIは、エンドポイントごとに特定のリソースを取得・作成・更新・削除できるため、直感的で理解しやすい設計になります。

@RestController
@RequestMapping("/users")
public class UserController {
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.getUserById(id);
    }
}
  • クライアントは GET /users/1 のようにリクエストを送るだけで、簡単にデータを取得可能

2.HTTPキャッシュの活用

@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
    User user = userService.getUserById(id);
    return ResponseEntity.ok()
            .cacheControl(CacheControl.maxAge(60, TimeUnit.SECONDS)) // 60秒キャッシュ
            .body(user);
}

  • ETagや Cache-Control を利用することで、不要なAPI呼び出しを抑えられる

2.2. REST APIの課題

課題 REST APIでの対応
オーバーフェッチ・アンダーフェッチ クライアントが必要としないデータまで取得 or 必要なデータを得るために複数回リクエストが必要
ダッシュボードなどのデータ集約が難しい 例えば、売上データ、ユーザー数、エラー発生件数を1画面に表示するには複数のAPIコールが必要
リアルタイムデータの取得が困難 一定間隔でポーリングが必要で、サーバー負荷が増加

このようなケースでは、 GraphQLを併用することで解決 できる可能性があります。

3. GraphQLの特徴とメリット

3.1. GraphQLの基本概念

GraphQLは、クライアントが取得したいデータを指定できるAPIクエリ言語 です。

GraphQL vs REST API

REST API GraphQL
データ取得 固定のエンドポイント 1つのエンドポイントで柔軟な取得
オーバーフェッチ 発生しやすい 必要なデータだけ取得可能
データ結合 クライアント側で複数APIを組み合わせる 1つのクエリで取得可能

3.2. GraphQLのメリット

1.必要なデータだけ取得できる(オーバーフェッチ・アンダーフェッチの解決)

REST API では、不要なデータまで取得してしまう(オーバーフェッチ)ことがある。 例えば、GET /users/1 で id, name, email, address, phone など すべての情報が返ってくる。

GraphQL では、取得したいフィールドだけ指定できる

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

📌 解説

id と name だけ を指定 → email や address など不要なデータは取得しない。
無駄なデータ転送がない ため、通信量を削減できる。

📌 レスポンス

{
  "data": {
    "user": {
      "id": 1,
      "name": "taro yamada"
    }
  }
}

🔹 REST API だとすべてのフィールドが返るが、GraphQL なら本当に必要なものだけ取得できる。

2. 複数のデータを1回のリクエストで取得

REST API では、複数のデータを取得する場合、複数のエンドポイントを叩く必要がある。 例えば、売上データとユーザー数を取得するには:

  • GET /sales → 売上データを取得
  • GET /users/count → ユーザー数を取得

GraphQL では、1回のクエリで実現できる。

query {
  sales {
    total
  }
  users {
    count
  }
}

📌 解説

  • sales(売上データ)と users(ユーザー数)を1回のクエリで取得できる
  • これにより、APIの呼び出し回数を減らし、パフォーマンス向上 につながる

📌 レスポンス

{
  "data": {
    "sales": {
      "total": 50000
    },
    "users": {
      "count": 1200
    }
  }
}

🔹 REST API だと2回のリクエストが必要だが、GraphQL なら1回のリクエストで取得可能!

3. リアルタイムデータの取得

REST API では、リアルタイムデータを取得するために、定期的にAPIをポーリング(一定間隔でリクエスト)する必要がある。

例えば

エラーログを監視する場合「GET /error-logs」 を 毎秒実行(ポーリング)することで、サーバー負荷が高くなるが、GraphQL の Subscription を使えば、リアルタイムでデータを受け取れる

subscription {
  newErrorLogs {
    timestamp
    message
  }
}

📌 解説

エラーログが発生すると、自動的にクライアントに通知される!
ポーリング不要! 必要なときだけデータを受け取れる。
📌 レスポンス例 (エラー発生時にサーバーから自動でデータが送られる)

{
  "data": {
    "newErrorLogs": {
      "timestamp": "2025-03-20T12:34:56Z",
      "message": "Database connection error"
    }
  }
}

🔹 REST API のポーリングとは違い、GraphQL の Subscription なら、必要なときだけリアルタイムで通知が届く

4. REST APIとGraphQLの併用戦略

API REST API GraphQL
CRUD操作 ✅ 適している ⚠️ 過剰設計の可能性
ダッシュボード ⚠️ API呼び出しが増える ✅ 最適化できる
リアルタイムデータ ⚠️ ポーリングが必要 ✅ Subscriptionで対応

5. キャッシュ戦略とリアルタイムデータの取得

5.1. HTTPキャッシュが使えない理由

REST APIでは、Cache-ControlETag を利用してリクエスト/レスポンスモデル に基づいたキャッシュが可能ですが、GraphQLのリアルタイムデータ取得では WebSocket (Subscription) を利用するため適用できません。

また、GraphQLはすべてのリクエストが /graphql という1つのエンドポイントに対して行われるため、従来のREST APIのように GET /users/1 のレスポンスを個別にキャッシュすることが難しくなります。


5.2. GraphQLにおけるキャッシュ戦略

GraphQLでは、以下の方法でキャッシュを最適化できます。

1. Apollo Clientによるクライアントキャッシュ

const { data } = useQuery(GET_USER, {
 variables: { id: 1 },
 fetchPolicy: "cache-first",
});

2.Redisを使ったサーバーキャッシュ

@GraphQLQuery(name = "user")
public User getUser(@GraphQLArgument(name = "id") Long id) {
    return cacheService.getCachedUser(id, () -> userService.getUserById(id));
}

6. まとめ

REST APIは CRUD操作やHTTPキャッシュを活用したデータ取得 に適していますが、リアルタイムデータの取得や複数データの統合にはGraphQLが効果的 です。

API設計 REST API (HTTPキャッシュ) GraphQL (WebSocket/Subscription)
データ取得方式 クライアントがリクエスト サーバーがプッシュ
キャッシュの適用 HTTPキャッシュ (Cache-Control, ETag) Apollo Client, Redis
リアルタイム性 ポーリングが必要 WebSocketで即時更新

REST APIを基本にしつつ、ダッシュボードやリアルタイムデータの取得にはGraphQLを併用 することで、より柔軟なAPI設計が可能になります。今後、データ取得の最適化を検討する際には、GraphQLの導入も視野に入れてみましょう。

おまけ、

項目 REST API GraphQL gRPC WebSocket
通信プロトコル HTTP HTTP HTTP/2 TCP
データフォーマット JSON, XML JSON Protocol Buffers (Protobuf) JSON, バイナリデータ
主な用途 一般的なWeb API 柔軟なデータ取得が必要なAPI 高速な通信・マイクロサービス間通信 双方向・リアルタイム通信
オーバーフェッチ 発生しやすい 発生しにくい 発生しにくい なし
アンダーフェッチ 発生しやすい 発生しにくい 発生しにくい なし
リアルタイム通信 WebSocket併用で可能 サブスクリプション機能で可能 双方向ストリーミングが可能 可能
パフォーマンス 低~中(JSONのオーバーヘッドあり) 中(1回のリクエストで多くのデータ取得可) 高(バイナリ通信、高速圧縮) 高(常時接続)
スキーマ定義 必須ではない Schema(型定義)必須 .protoファイル必須 なし
クライアントのサポート 広範(ほぼ全ての環境で対応) 広範(フロントエンドとの連携が容易) 言語ごとに専用のgRPCライブラリが必要 ブラウザ・モバイルアプリなどで利用
主な利用例 RESTful API, Webサービス ダッシュボード, フレキシブルなAPI マイクロサービス, IoT チャット, ゲーム, 金融取引
1
2
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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?