mcpField
G
graphql-architect

graphql-architect

github.com/404kidwiz開発91 回インストール
リポジトリ

graphql-architect について

API の設計・最適化に取り組む開発者向けの GraphQL アーキテクチャスキルです。スキーマ設計、フェデレーション、リゾルバー最適化、リアルタイムサブスクリプションを扱います。

主な機能

  1. 01型安全なスキーマ設計
  2. 02フェデレーションとスキーマ合成
  3. 03DataLoader による N+1 対策
  4. 04リゾルバーのキャッシュとクエリ制限
  5. 05WebSocket サブスクリプションのパターン

活用シーン

  1. 01新しい GraphQL API の設計
  2. 02マイクロサービス間のスキーマ統合
  3. 03リゾルバーの N+1 クエリ削減
  4. 04リアルタイムサブスクリプションの追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/404kidwiz/claude-supercode-skills --skill graphql-architect

インストール後、Claude Code で/graphql-architectを入力して読み込まれたか確認します。

同梱ファイルEXAMPLES.mdREFERENCE.md

詳細

GraphQL アーキテクトスキル

目的

スキーマ設計、フェデレーションパターン、リゾルバーの最適化、リアルタイムサブスクリプションを専門とする、GraphQL アーキテクチャの専門知識を提供します。N+1 問題の防止、効率的なキャッシュ、分散システム全体でスケーラブルな API ゲートウェイパターンを備えた、高性能で型安全な GraphQL API を構築します。

使用する場面

  • 新しい API の GraphQL スキーマをゼロから設計する
  • 複数のサービスにまたがる GraphQL フェデレーションを実装する
  • N+1 クエリを防ぐためにリゾルバーを最適化する(DataLoader の実装)
  • GraphQL サブスクリプションでリアルタイム機能を構築する
  • REST から GraphQL に移行する、または REST と GraphQL のハイブリッド API を設計する
  • GraphQL API ゲートウェイパターンを実装する

クイックスタート

このスキルを呼び出す場面:

  • 新しい GraphQL スキーマまたはフェデレーションアーキテクチャを設計する
  • N+1 クエリのパフォーマンス問題を解決する
  • リアルタイムサブスクリプションを実装する
  • REST API を GraphQL に移行する

呼び出さない場面:

  • シンプルな REST API で十分な場合(api-designer を使用)
  • API 層を伴わないデータベーススキーマ設計の場合(database-administrator を使用)
  • フロントエンドのデータ取得のみの場合(frontend-developer を使用)

主な機能

スキーマ設計
  • ベストプラクティスに基づいた型安全な GraphQL スキーマの作成
  • ページネーションパターン(Relay、オフセットベース)の実装
  • 入力検証とエラー処理を備えたミューテーションの設計
  • スキーマの進化と後方互換性の管理
フェデレーションアーキテクチャ
  • マイクロサービス向けの Apollo Federation の実装
  • サービスの合成に向けたスキーマステッチングの設定
  • サービス間のクエリとミューテーションの管理
  • スキーマ合成のための API ゲートウェイの構築
リゾルバーの最適化
  • N+1 問題を防ぐための DataLoader の実装
  • リゾルバーおよびフィールドレベルでのキャッシュ戦略
  • クエリの複雑度分析と深度制限
  • 本番環境の最適化に向けた永続化クエリ
リアルタイムサブスクリプション
  • WebSocket ベースのサブスクリプションの実装
  • サブスクリプションのライフサイクルとクリーンアップの管理
  • イベント駆動型バックエンドとの統合
  • サブスクリプションの認証と認可への対応

判断フレームワーク

GraphQL と REST の判断基準
要素GraphQL を使用REST を使用
クライアントの種類ニーズが異なる複数のクライアントニーズが予測可能な単一のクライアント
データの関係性入れ子が深く、相互に関連するデータ関係性が少ないフラットなリソース
過剰なデータ取得クライアントごとに必要なデータの一部が異なるクライアントが通常すべてのフィールドを必要とする
データ取得の不足複数回の往復を避けたい単一のエンドポイントで十分なデータを提供できる
スキーマの進化頻繁に変更があり、後方互換性が必要API が安定しており、バージョン管理が許容される
リアルタイム性サブスクリプションが必要ポーリングまたは Webhook で十分
スキーマ設計の判断フロー
Schema Design Requirements
│
├─ Single service (monolith)?
│  └─ Schema-first design with single schema
│
├─ Multiple microservices?
│  ├─ Services owned by different teams?
│  │  └─ Apollo Federation
│  └─ Services owned by same team?
│     └─ Schema stitching (simpler)
│
├─ Existing REST APIs to wrap?
│  └─ GraphQL wrapper layer
│
└─ Need backward compatibility?
   └─ Hybrid REST + GraphQL
N+1 問題の防止戦略
Resolver Implementation
│
├─ Field resolves to single related entity?
│  └─ DataLoader with batching
│
├─ Field resolves to list of related entities?
│  ├─ List size always small (<10)?
│  │  └─ Direct query acceptable
│  └─ List size unbounded?
│     └─ DataLoader with batching + pagination
│
├─ Nested resolvers (users → posts → comments)?
│  └─ Multi-level DataLoaders
│
└─ Aggregations or counts?
   └─ Separate DataLoader for counts

主なワークフロー:DataLoader の実装

問題:N+1 クエリによるパフォーマンス低下

// WITHOUT DataLoader - N+1 problem
const resolvers = {
  Post: {
    author: async (post, _, { db }) => {
      // Executed once per post (N+1 problem!)
      return db.User.findByPk(post.userId);
    }
  }
};
// Query for 100 posts triggers 101 DB queries

解決策:DataLoader でバッチ処理する

import DataLoader from 'dataloader';

// Create loader per request (important!)
function createLoaders(db) {
  return {
    userLoader: new DataLoader(async (userIds) => {
      const users = await db.User.findAll({
        where: { id: userIds }
      });
      // Return in same order as requested IDs
      const userMap = new Map(users.map(u => [u.id, u]));
      return userIds.map(id => userMap.get(id));
    })
  };
}

// Resolver using DataLoader
const resolvers = {
  Post: {
    author: (post, _, { loaders }) => {
      return loaders.userLoader.load(post.userId);
    }
  }
};
// Same query now triggers 2 queries total!

クイックリファレンス:スキーマのベストプラクティス

ページネーションパターン(Relay 形式)
type Query {
  users(first: Int, after: String, last: Int, before: String): UserConnection!
}

type UserConnection {
  edges: [UserEdge!]!
  pageInfo: PageInfo!
  totalCount: Int!
}

type UserEdge {
  node: User!
  cursor: String!
}

type PageInfo {
  hasNextPage: Boolean!
  hasPreviousPage: Boolean!
  startCursor: String
  endCursor: String
}
エラー処理パターン
type Mutation {
  createUser(input: CreateUserInput!): CreateUserPayload!
}

type CreateUserPayload {
  user: User
  errors: [UserError!]!
}

type UserError {
  field: String
  message: String!
  code: ErrorCode!
}

enum ErrorCode {
  VALIDATION_ERROR
  NOT_FOUND
  UNAUTHORIZED
  CONFLICT
}

危険信号 — エスカレーションが必要な場合

状況エスカレーションが必要な理由
クエリの複雑度が急増している入れ子に制限のないクエリによる DoS の可能性
フェデレーションに循環依存があるスキーマ設計の問題
同時接続中のサブスクリプションが 10K 以上インフラストラクチャアーキテクチャの問題
50 以上のフィールドにまたがるスキーマのバージョン管理破壊的変更の管理
サービス間トランザクションが必要分散システムのパターン

追加リソース

  • 詳細な技術リファレンス:REFERENCE.md を参照

    • Apollo Federation のセットアップワークフロー
    • フィールド単位の認可ディレクティブ
    • クエリの複雑度制限
  • コード例とパターン:EXAMPLES.md を参照

    • アンチパターン(N+1 クエリ、複雑度制限なし)
    • 他のスキルとの統合パターン
    • リゾルバーの完全な実装

コメント