DEV Community

myougaTheAxo
myougaTheAxo

Posted on • Originally published at zenn.dev

Claude CodeでGraphQL Federationを設計する:サブグラフ分割・@key・ゲートウェイ統合

CLAUDE.mdルール

GraphQL Federationの設計では、サブグラフの境界設計とエンティティ参照が核心です。Claude Codeを使った設計・実装ワークフローを解説します。

# CLAUDE.md
## GraphQL Federation設計ルール
- サブグラフはドメイン境界(ユーザー/商品/注文)で分割する
- @keyディレクティブでエンティティのプライマリキーを明示する
- @externalと@requiresで他サブグラフのフィールドを参照する
- ゲートウェイはApollo Routerを使い、supergraphスキーマを自動合成する
Enter fullscreen mode Exit fullscreen mode

サブグラフ分割の設計

Federationでは各サービスが独立したGraphQLスキーマを持ちます。

import { buildSubgraphSchema } from "@apollo/subgraph";
import { gql } from "graphql-tag";

const userTypeDefs = gql`
  extend schema @link(url: "https://specs.apollo.dev/federation/v2.0",
    import: ["@key", "@shareable"])

  type User @key(fields: "id") {
    id: ID!
    name: String!
    email: String!
    createdAt: String!
  }

  type Query {
    user(id: ID!): User
    users: [User!]!
  }
`;

const userResolvers = {
  User: {
    __resolveReference(ref: { id: string }) {
      return userRepository.findById(ref.id);
    },
  },
  Query: {
    user: (_: unknown, { id }: { id: string }) => userRepository.findById(id),
    users: () => userRepository.findAll(),
  },
};

export const userSchema = buildSubgraphSchema({ typeDefs: userTypeDefs, resolvers: userResolvers });
Enter fullscreen mode Exit fullscreen mode

@keyと@requiresでエンティティを参照する

Ordersサブグラフからユーザー情報を参照する実装です。

const orderTypeDefs = gql`
  extend schema @link(url: "https://specs.apollo.dev/federation/v2.0",
    import: ["@key", "@external", "@requires"])

  type User @key(fields: "id") {
    id: ID!
    email: String! @external
    orders: [Order!]!
  }

  type Order @key(fields: "id") {
    id: ID!
    userId: ID!
    items: [OrderItem!]!
    totalAmount: Float!
    status: OrderStatus!
  }

  enum OrderStatus { PENDING CONFIRMED SHIPPED DELIVERED }

  type OrderItem {
    productId: ID!
    quantity: Int!
    price: Float!
  }

  type Query {
    order(id: ID!): Order
    ordersByUser(userId: ID!): [Order!]!
  }
`;

const orderResolvers = {
  User: {
    orders: (user: { id: string }) => orderRepository.findByUserId(user.id),
  },
  Order: {
    __resolveReference: (ref: { id: string }) => orderRepository.findById(ref.id),
  },
};
Enter fullscreen mode Exit fullscreen mode

Apollo RouterでSupergraphを構成する

# router.yaml
supergraph:
  listen: 0.0.0.0:4000

subgraphs:
  users:
    routing_url: http://users-service:4001/graphql
  orders:
    routing_url: http://orders-service:4002/graphql
  products:
    routing_url: http://products-service:4003/graphql

cors:
  origins:
    - https://your-frontend.example.com
  allow_credentials: true

headers:
  all:
    request:
      - propagate:
          named: Authorization
Enter fullscreen mode Exit fullscreen mode

Rover CLIでスキーマを合成してRouterを起動します:

rover supergraph compose --config supergraph.yaml > supergraph.graphql
./router --config router.yaml --supergraph supergraph.graphql
Enter fullscreen mode Exit fullscreen mode

まとめ

  • @keyディレクティブでエンティティのプライマリキーを宣言し、ゲートウェイが自動的にサブグラフ間の参照を解決する
  • @externalと@requiresを使って他サブグラフのフィールドを宣言なしに参照でき、ドメインをまたいだデータ結合が可能になる
  • Apollo RouterはRustベースで高性能、YAML設定でCORSやヘッダープロパゲーションを簡潔に記述できる
  • Claude Codeにsupergraphスキーマを渡すことで、N+1検出・DataLoader実装・エラーハンドリング改善まで一気に自動化できる

マイクロサービス設計のセキュリティを強化したい方へ:Security Pack(¥1,480) — Claude Code用セキュリティレビュープロンプト集。認証・認可・インジェクション対策を自動チェック。

Top comments (0)