ストーリー
あなた
で、結局RESTとGraphQLどっちを使えばいいんですか?
あ
高
高橋アーキテクト
よくある質問だ。答えは”場合による”。でもそれだと判断できないから、具体的な判断基準を教えよう
高
高橋アーキテクト
ない。だからこそ、両方を理解して適切に使い分ける力が必要なんだ。それが設計者の仕事だ
7つの観点で比較
1. データ取得の柔軟性
// REST: サーバーが返すデータ構造が固定
GET /api/v1/users/123
// → 常に全フィールドが返る(name, email, bio, avatar, settings, ...)
// モバイルアプリでは name と avatar だけ欲しい場合でも全部返る
// GraphQL: クライアントが欲しいフィールドだけ指定
query { user(id: "123") { name, avatarUrl } }
// → 指定したフィールドだけ返る(帯域節約)
| REST | GraphQL |
|---|
| 柔軟性 | 低(固定レスポンス) | 高(クライアントが指定) |
| Over-fetching | 発生しやすい | 発生しない |
| Under-fetching | 複数リクエスト必要 | 1リクエストで解決 |
2. キャッシュ
// REST: HTTPキャッシュが効く
GET /api/v1/users/123
// → Cache-Control, ETag で自然にキャッシュ可能
// CDNでもキャッシュ可能
// GraphQL: すべてPOST /graphql → HTTPキャッシュが効かない
POST /graphql
// → APQ(Automatic Persisted Queries)や
// クライアント側キャッシュ(Apollo Client)で対応
| REST | GraphQL |
|---|
| HTTPキャッシュ | 自然に利用可能 | 困難(POSTリクエスト) |
| CDNキャッシュ | 容易 | 工夫が必要 |
| クライアントキャッシュ | 独自実装 | Apollo Client等が自動管理 |
3. エラーハンドリング
// REST: HTTPステータスコードで明確
// 404 Not Found → リソースが存在しない
// 401 Unauthorized → 認証エラー
// GraphQL: 常に200 OK、エラーは errors フィールドに入る
{
"data": { "user": null },
"errors": [
{
"message": "ユーザーが見つかりません",
"locations": [{ "line": 2, "column": 3 }],
"path": ["user"],
"extensions": {
"code": "NOT_FOUND"
}
}
]
}
// → 部分的な成功(一部のフィールドだけエラー)も可能
4. 学習コストとツール
| REST | GraphQL |
|---|
| 学習コスト | 低(HTTP知識があれば) | 中〜高(専用の概念が多い) |
| ツール | curl, Postman | Apollo Studio, GraphiQL |
| エコシステム | 成熟・豊富 | 急速に成長中 |
| デバッグ | ブラウザのDevToolsで容易 | 専用ツールが必要 |
5. バージョニング
// REST: URLやヘッダーでバージョン管理
GET /api/v1/users/123 // v1
GET /api/v2/users/123 // v2
// GraphQL: バージョニングしない
// 代わりに @deprecated ディレクティブで段階的に移行
type User {
name: String!
fullName: String! # 新しいフィールド
username: String @deprecated(reason: "Use 'name' instead") # 非推奨
}
// → フィールドを追加しても既存クエリに影響なし
// → 使われなくなったフィールドを段階的に削除
6. セキュリティ
| REST | GraphQL |
|---|
| 攻撃対象 | 各エンドポイント | 単一エンドポイント |
| 認可粒度 | エンドポイント単位 | フィールド単位も可能 |
| DDoS対策 | レート制限が容易 | クエリの複雑さ制限が必要 |
| クエリ制御 | サーバーが完全制御 | クライアントが自由にクエリ可能 |
7. パフォーマンス
| REST | GraphQL |
|---|
| ネットワーク | 複数リクエスト | 1リクエスト |
| ペイロードサイズ | 固定(Over-fetchingあり) | 最小(必要なデータのみ) |
| サーバー負荷 | 予測しやすい | クエリ次第で変動 |
| N+1問題 | ORM側で対処 | DataLoader必須 |
判断フローチャート
API の主要な利用者は?
├── サードパーティ(外部開発者)
│ └── REST(HTTPの標準的な使い方で理解しやすい)
│
├── 自社のフロントエンド
│ ├── モバイルアプリ(帯域が重要)
│ │ └── GraphQL(必要最小限のデータ取得)
│ │
│ ├── 複雑なダッシュボード(多数のデータソース)
│ │ └── GraphQL(1リクエストで複数データ取得)
│ │
│ └── シンプルなWebアプリ
│ └── REST(シンプルで十分)
│
├── マイクロサービス間通信
│ └── REST または gRPC(シンプルで高速)
│
└── リアルタイム通信が必要
└── GraphQL Subscription または WebSocket
実プロジェクトでの使い分け事例
// パターン1: REST + GraphQL のハイブリッド
// 公開API: REST(サードパーティ向け)
// 内部API: GraphQL(自社フロントエンド向け)
// パターン2: BFF(Backend for Frontend)
// モバイルアプリ向け: GraphQL BFF
// 管理画面向け: REST API
// バックエンドサービス間: gRPC
// パターン3: 段階的移行
// 既存REST APIはそのまま維持
// 新機能をGraphQLで追加
// GraphQLサーバーが内部でREST APIを呼び出す
まとめ
| 場面 | 推奨 | 理由 |
|---|
| 公開API | REST | 標準的、キャッシュ容易、学習コスト低 |
| モバイルアプリ | GraphQL | 帯域節約、柔軟なデータ取得 |
| 複雑なUI | GraphQL | 複数リソースの一括取得 |
| CRUD中心 | REST | シンプルで十分 |
| マイクロサービス間 | REST/gRPC | シンプル、高パフォーマンス |
| リアルタイム | GraphQL Subscription | 組み込みのサポート |
チェックリスト
次のステップへ
RESTとGraphQLの使い分けを学びました。
次は演習です。実際にGraphQL APIのスキーマを設計してみましょう。
推定読了時間: 40分