jpskill.com
💼 ビジネス コミュニティ

graphql-schema

GraphQLのクエリやミューテーションを作成したり、Apollo Clientを利用したり、型を生成したりする際に、GraphQLのスキーマやコード生成パターンを効果的に活用するSkill。

📜 元の英語説明(参考)

GraphQL queries, mutations, and code generation patterns. Use when creating GraphQL operations, working with Apollo Client, or generating types.

🇯🇵 日本人クリエイター向け解説

一言でいうと

GraphQLのクエリやミューテーションを作成したり、Apollo Clientを利用したり、型を生成したりする際に、GraphQLのスキーマやコード生成パターンを効果的に活用するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o graphql-schema.zip https://jpskill.com/download/17834.zip && unzip -o graphql-schema.zip && rm graphql-schema.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/17834.zip -OutFile "$d\graphql-schema.zip"; Expand-Archive "$d\graphql-schema.zip" -DestinationPath $d -Force; ri "$d\graphql-schema.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して graphql-schema.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → graphql-schema フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

GraphQLスキーマパターン

コアなルール

  1. gqlリテラルをインラインで記述しない - .gqlファイルを作成してください
  2. .gqlファイルを作成/変更した後は必ずcodegenを実行してください
  3. mutationには必ずonErrorハンドラーを追加してください
  4. 生成されたhooksを使用してください - 生のApollo hooksを記述しないでください

ファイル構造

src/
├── components/
│   └── ItemList/
│       ├── ItemList.tsx
│       ├── GetItems.gql           # クエリ定義
│       └── GetItems.generated.ts  # 自動生成 (編集しないでください)
└── graphql/
    └── mutations/
        └── CreateItem.gql         # 共有mutation

クエリの作成

ステップ1: .gqlファイルを作成

# src/components/ItemList/GetItems.gql
query GetItems($limit: Int, $offset: Int) {
  items(limit: $limit, offset: $offset) {
    id
    name
    description
    createdAt
  }
}

ステップ2: codegenを実行

npm run gql:typegen

ステップ3: 生成されたhookをインポートして使用

import { useGetItemsQuery } from './GetItems.generated';

const ItemList = () => {
  const { data, loading, error, refetch } = useGetItemsQuery({
    variables: { limit: 20, offset: 0 },
  });

  if (error) return <ErrorState error={error} onRetry={refetch} />;
  if (loading && !data) return <LoadingSkeleton />;
  if (!data?.items.length) return <EmptyState />;

  return <List items={data.items} />;
};

Mutationの作成

ステップ1: .gqlファイルを作成

# src/graphql/mutations/CreateItem.gql
mutation CreateItem($input: CreateItemInput!) {
  createItem(input: $input) {
    id
    name
    description
  }
}

ステップ2: codegenを実行

npm run gql:typegen

ステップ3: 必須のエラー処理とともに使用

import { useCreateItemMutation } from 'graphql/mutations/CreateItem.generated';

const CreateItemForm = () => {
  const [createItem, { loading }] = useCreateItemMutation({
    // 成功時の処理
    onCompleted: (data) => {
      toast.success({ title: 'Item created' });
      navigation.goBack();
    },
    // エラー処理は必須です
    onError: (error) => {
      console.error('createItem failed:', error);
      toast.error({ title: 'Failed to create item' });
    },
    // キャッシュの更新
    update: (cache, { data }) => {
      if (data?.createItem) {
        cache.modify({
          fields: {
            items: (existing = []) => [...existing, data.createItem],
          },
        });
      }
    },
  });

  return (
    <Button
      onPress={() => createItem({ variables: { input: formValues } })}
      isDisabled={!isValid || loading}
      isLoading={loading}
    >
      Create
    </Button>
  );
};

Mutation UIの要件

重要: すべてのmutationトリガーは以下を満たす必要があります:

  1. mutation中は無効化する - ダブルクリックを防止
  2. ローディング状態を表示する - 視覚的なフィードバック
  3. onErrorハンドラーを持つ - ユーザーに失敗を知らせる
  4. 成功時のフィードバックを表示する - ユーザーに成功を知らせる
// 正しい - 完全なmutationパターン
const [submit, { loading }] = useSubmitMutation({
  onError: (error) => {
    console.error('submit failed:', error);
    toast.error({ title: 'Save failed' });
  },
  onCompleted: () => {
    toast.success({ title: 'Saved' });
  },
});

<Button
  onPress={handleSubmit}
  isDisabled={!isValid || loading}
  isLoading={loading}
>
  Submit
</Button>

クエリのオプション

フェッチポリシー

Policy 使用場面
cache-first データがほとんど変更されない場合
cache-and-network 高速性と最新性を両立したい場合 (デフォルト)
network-only 常に最新の情報が必要な場合
no-cache キャッシュを一切使用しない場合 (まれ)

一般的なオプション

useGetItemsQuery({
  variables: { id: itemId },

  // フェッチ戦略
  fetchPolicy: 'cache-and-network',

  // ネットワークステータスの変更時に再レンダリング
  notifyOnNetworkStatusChange: true,

  // 条件が満たされない場合はスキップ
  skip: !itemId,

  // 更新をポーリング
  pollInterval: 30000,
});

楽観的アップデート

UIに即座にフィードバックを与える場合:

const [toggleFavorite] = useToggleFavoriteMutation({
  optimisticResponse: {
    toggleFavorite: {
      __typename: 'Item',
      id: itemId,
      isFavorite: !currentState,
    },
  },
  onError: (error) => {
    // ロールバックは自動的に行われます
    console.error('toggleFavorite failed:', error);
    toast.error({ title: 'Failed to update' });
  },
});

楽観的アップデートを使用すべきでない場合

  • バリデーションに失敗する可能性のある操作
  • サーバーで生成された値を使用する操作
  • 破壊的な操作 (削除)
  • 他のユーザーに影響を与える操作

フラグメント

再利用可能なフィールド選択の場合:

# src/graphql/fragments/ItemFields.gql
fragment ItemFields on Item {
  id
  name
  description
  createdAt
  updatedAt
}

クエリでの使用:

query GetItems {
  items {
    ...ItemFields
  }
}

アンチパターン

// 間違い - インラインのgql
const GET_ITEMS = gql`
  query GetItems { items { id } }
`;

// 正しい - .gqlファイル + 生成されたhookを使用
import { useGetItemsQuery } from './GetItems.generated';


// 間違い - エラーハンドラーがない
const [mutate] = useMutation(MUTATION);

// 正しい - 常にエラーを処理する
const [mutate] = useMutation(MUTATION, {
  onError: (error) => {
    console.error('mutation failed:', error);
    toast.error({ title: 'Operation failed' });
  },
});


// 間違い - mutation中にボタンが無効化されていない
<Button onPress={submit}>Submit</Button>

// 正しい - 無効化とローディング
<Button onPress={submit} isDisabled={loading} isLoading={loading}>
  Submit
</Button>

Codegenコマンド

# .gqlファイルから型を生成
npm run gql:typegen

# スキーマをダウンロード + 型を生成
npm run sync-types

他のSkillとの連携

  • react-ui-patterns: クエリのローディング/エラー/空の状態
  • testing-patterns: テストで生成されたhooksをモックする
  • formik-patterns: Mutationの送信パターン
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

GraphQL Schema Patterns

Core Rules

  1. NEVER inline gql literals - Create .gql files
  2. ALWAYS run codegen after creating/modifying .gql files
  3. ALWAYS add onError handler to mutations
  4. Use generated hooks - Never write raw Apollo hooks

File Structure

src/
├── components/
│   └── ItemList/
│       ├── ItemList.tsx
│       ├── GetItems.gql           # Query definition
│       └── GetItems.generated.ts  # Auto-generated (don't edit)
└── graphql/
    └── mutations/
        └── CreateItem.gql         # Shared mutations

Creating a Query

Step 1: Create .gql file

# src/components/ItemList/GetItems.gql
query GetItems($limit: Int, $offset: Int) {
  items(limit: $limit, offset: $offset) {
    id
    name
    description
    createdAt
  }
}

Step 2: Run codegen

npm run gql:typegen

Step 3: Import and use generated hook

import { useGetItemsQuery } from './GetItems.generated';

const ItemList = () => {
  const { data, loading, error, refetch } = useGetItemsQuery({
    variables: { limit: 20, offset: 0 },
  });

  if (error) return <ErrorState error={error} onRetry={refetch} />;
  if (loading && !data) return <LoadingSkeleton />;
  if (!data?.items.length) return <EmptyState />;

  return <List items={data.items} />;
};

Creating a Mutation

Step 1: Create .gql file

# src/graphql/mutations/CreateItem.gql
mutation CreateItem($input: CreateItemInput!) {
  createItem(input: $input) {
    id
    name
    description
  }
}

Step 2: Run codegen

npm run gql:typegen

Step 3: Use with REQUIRED error handling

import { useCreateItemMutation } from 'graphql/mutations/CreateItem.generated';

const CreateItemForm = () => {
  const [createItem, { loading }] = useCreateItemMutation({
    // Success handling
    onCompleted: (data) => {
      toast.success({ title: 'Item created' });
      navigation.goBack();
    },
    // ERROR HANDLING IS REQUIRED
    onError: (error) => {
      console.error('createItem failed:', error);
      toast.error({ title: 'Failed to create item' });
    },
    // Cache update
    update: (cache, { data }) => {
      if (data?.createItem) {
        cache.modify({
          fields: {
            items: (existing = []) => [...existing, data.createItem],
          },
        });
      }
    },
  });

  return (
    <Button
      onPress={() => createItem({ variables: { input: formValues } })}
      isDisabled={!isValid || loading}
      isLoading={loading}
    >
      Create
    </Button>
  );
};

Mutation UI Requirements

CRITICAL: Every mutation trigger must:

  1. Be disabled during mutation - Prevent double-clicks
  2. Show loading state - Visual feedback
  3. Have onError handler - User knows it failed
  4. Show success feedback - User knows it worked
// CORRECT - Complete mutation pattern
const [submit, { loading }] = useSubmitMutation({
  onError: (error) => {
    console.error('submit failed:', error);
    toast.error({ title: 'Save failed' });
  },
  onCompleted: () => {
    toast.success({ title: 'Saved' });
  },
});

<Button
  onPress={handleSubmit}
  isDisabled={!isValid || loading}
  isLoading={loading}
>
  Submit
</Button>

Query Options

Fetch Policies

Policy Use When
cache-first Data rarely changes
cache-and-network Want fast + fresh (default)
network-only Always need latest
no-cache Never cache (rare)

Common Options

useGetItemsQuery({
  variables: { id: itemId },

  // Fetch strategy
  fetchPolicy: 'cache-and-network',

  // Re-render on network status changes
  notifyOnNetworkStatusChange: true,

  // Skip if condition not met
  skip: !itemId,

  // Poll for updates
  pollInterval: 30000,
});

Optimistic Updates

For instant UI feedback:

const [toggleFavorite] = useToggleFavoriteMutation({
  optimisticResponse: {
    toggleFavorite: {
      __typename: 'Item',
      id: itemId,
      isFavorite: !currentState,
    },
  },
  onError: (error) => {
    // Rollback happens automatically
    console.error('toggleFavorite failed:', error);
    toast.error({ title: 'Failed to update' });
  },
});

When NOT to Use Optimistic Updates

  • Operations that can fail validation
  • Operations with server-generated values
  • Destructive operations (delete)
  • Operations affecting other users

Fragments

For reusable field selections:

# src/graphql/fragments/ItemFields.gql
fragment ItemFields on Item {
  id
  name
  description
  createdAt
  updatedAt
}

Use in queries:

query GetItems {
  items {
    ...ItemFields
  }
}

Anti-Patterns

// WRONG - Inline gql
const GET_ITEMS = gql`
  query GetItems { items { id } }
`;

// CORRECT - Use .gql file + generated hook
import { useGetItemsQuery } from './GetItems.generated';


// WRONG - No error handler
const [mutate] = useMutation(MUTATION);

// CORRECT - Always handle errors
const [mutate] = useMutation(MUTATION, {
  onError: (error) => {
    console.error('mutation failed:', error);
    toast.error({ title: 'Operation failed' });
  },
});


// WRONG - Button not disabled during mutation
<Button onPress={submit}>Submit</Button>

// CORRECT - Disabled and loading
<Button onPress={submit} isDisabled={loading} isLoading={loading}>
  Submit
</Button>

Codegen Commands

# Generate types from .gql files
npm run gql:typegen

# Download schema + generate types
npm run sync-types

Integration with Other Skills

  • react-ui-patterns: Loading/error/empty states for queries
  • testing-patterns: Mock generated hooks in tests
  • formik-patterns: Mutation submission patterns