Chuyển đến nội dung chính

レッスン 19: GraphQL フェデレーション — マイクロ フロントエンド用の統合 API

アポロ連合: スーパーグラフ、サブグラフ、ルーター。各マイクロサービスは GraphQL サブグラフを公開します。ルーターは統一された API として構成されます。スキーマステッチング対フェデレーション。パフォーマンスに関する考慮事項。

🏗️ アーキテクチャ — レッスン 19 レッスン 19: GraphQL フェデレーション — 統合 API マイクロフロントエンド用

マイクロサービスとマイクロ フロントエンドのシステム設計 — 基本から運用まで

パート 6: API ゲートウェイと BFF レイヤー

xdev.asia

はじめに

GraphQL フェデレーションにより、各マイクロサービスが サブグラフを公開できるようになり、ルーターはそれを 統合スーパーグラフに自動的に構成します。フロントエンドでは、すべてのサービスからデータをクエリするために 1 つのエンドポイントのみが必要です。

GraphQL Federation — 複数のサブグラフからの統合グラフ


1. 問題: 複数の GraphQL エンドポイント

❌ Mỗi service có GraphQL endpoint riêng:
Frontend → product.api.com/graphql (Product schema)
Frontend → user.api.com/graphql (User schema)
Frontend → order.api.com/graphql (Order schema)

→ Frontend phải biết endpoint nào chứa data gì
→ Không thể query cross-service trong 1 request
→ Ví dụ: Order + Product + User = 3 requests

2. GraphQL フェデレーション アーキテクチャ

✅ Unified Supergraph:

┌─────────────┐
│   Frontend  │
│  1 endpoint │
└──────┬──────┘
       │
       ▼
┌──────────────────────┐
│   Apollo Router      │
│   (Supergraph)       │
│   gateway.api.com    │
└──┬────────┬────────┬─┘
   │        │        │
   ▼        ▼        ▼
┌──────┐ ┌──────┐ ┌──────┐
│Product│ │ User │ │Order │
│Subgra│ │Subgra│ │Subgra│
│  ph  │ │  ph  │ │  ph  │
└──────┘ └──────┘ └──────┘

1 query → Router splits → Subgraphs → Router merges → 1 response

3. サブグラフの定義

3.1 製品サブグラフ

# Product Service subgraph
type Product @key(fields: "id") {
  id: ID!
  name: String!
  price: Float!
  description: String
  category: Category!
}

type Category {
  id: ID!
  name: String!
}

type Query {
  product(id: ID!): Product
  products(limit: Int, offset: Int): [Product!]!
}

3.2 サブグラフの確認 (製品の拡張)

# Review Service subgraph — extends Product
type Product @key(fields: "id") {
  id: ID!
  reviews: [Review!]!
  averageRating: Float
}

type Review {
  id: ID!
  rating: Int!
  comment: String
  author: User!
}

type Query {
  reviews(productId: ID!): [Review!]!
}

3.3 フェデレーションクエリ

# Frontend query — Router handles cross-service resolution
query ProductPage($id: ID!) {
  product(id: $id) {
    id              # → Product Subgraph
    name            # → Product Subgraph
    price           # → Product Subgraph
    reviews {       # → Review Subgraph
      rating
      comment
      author {      # → User Subgraph
        name
        avatar
      }
    }
    averageRating   # → Review Subgraph
  }
}

自動ルーター:

  1. 製品サブグラフのクエリ → 製品データの取得
  2. レビュー サブグラフをクエリ → レビューを取得 (product.id を使用)
  3. ユーザー サブグラフをクエリ → 著者情報を取得 (review.author.id を使用)
  4. すべて結合 → 1 つの応答を返す

4. スキーマステッチングとフェデレーション

スキーマの結合連盟
所有権ゲートウェイがスキーマを所有サービス独自のスキーマ
カップリング高 (ゲートウェイはサービスを認識しています)低 (サービス自体が宣言)
スケーラビリティゲートウェイのボトルネック分散
進化ハード(センターチェンジ)簡単 (サービスレベル)
評決❌ レガシー✅ おすすめ

5. パフォーマンスに関する考慮事項

5.1 クエリプランの最適化

Router tạo query plan tối ưu:
─ Parallel: Product + User subgraphs (independent)
─ Sequential: Reviews → after Product (needs product.id)

5.2 データローダーのパターン

// Trong Review Subgraph, batch user lookups
const userLoader = new DataLoader(async (userIds) => {
  const users = await userService.getUsers(userIds);
  return userIds.map(id => users.find(u => u.id === id));
});

// Resolve author field
Review: {
  author: (review) => userLoader.load(review.authorId)
}

5.3 キャッシュ

Persisted Queries: Client gửi query hash thay vì full query
Automatic Persisted Queries (APQ): Router cache query plans
CDN caching: @cacheControl directive

6. フェデレーションをいつ使用するか?

✅ Dùng khi:
- Nhiều microservices cần unified GraphQL API
- Frontend teams muốn 1 endpoint
- Complex, nested data relationships
- Multiple frontend clients

❌ Không cần khi:
- Chỉ có 1-2 services (đơn giản quá)
- REST đã đủ tốt
- Team chưa quen GraphQL
- Performance-critical (thêm latency qua Router)

概要

  • フェデレーション = 各サービス独自のサブグラフ、ルーターがスーパーグラフを構成
  • @key サブグラフ間のエンティティ参照のディレクティブ
  • ルーターは自動的にクエリを分割、解決、マージします
  • DataLoader パターンにより N+1 問題を回避
  • 複数のサービスに 統合された GraphQL API が必要な場合に使用します

次の記事: レッスン 20: マイクロサービスのテスト — ユニット、統合、E2E