mcpField
G
graphql

graphql

github.com/pluginagentmarketplace開発240 回インストール42 週間前に更新
リポジトリ

graphql について

graphqlは、Node.jsとApollo ServerによるGraphQL API構築を学ぶためのスキルです。スキーマ設計やリゾルバー、データアクセス、セキュリティ、サブスクリプション、性能、テストを基礎から応用まで扱います。

主な機能

  1. 01GraphQLスキーマとリゾルバーの解説
  2. 02Apollo Server設定例
  3. 03DataLoaderによるN+1対策
  4. 04認証と認可のパターン
  5. 05サブスクリプションとFederationの解説
  6. 06テストとエラー処理の例

活用シーン

  1. 01GraphQL API構築の学習
  2. 02リアルタイムサブスクリプションの追加
  3. 03N+1データ取得問題の軽減
  4. 04GraphQLクエリとミューテーションのテスト

インストール

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

$npx skills add https://github.com/pluginagentmarketplace/custom-plugin-nodejs --skill graphql

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

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
config.yaml
schema.json
references/
GUIDE.md
PATTERNS.md
scripts/
validate.py

詳細

Node.js を使用した GraphQL スキル

Apollo Server、型安全なスキーマ、リアルタイムサブスクリプションを活用して、柔軟で効率的な GraphQL API を構築する方法を習得します。

クイックスタート

GraphQL API を 4 ステップで作成します。

  1. スキーマを定義する - 型、クエリ、ミューテーション
  2. リゾルバーを作成する - データ取得ロジック
  3. サーバーをセットアップする - Apollo Server の設定
  4. データを接続する - データベースとの統合

主な概念

スキーマ定義(SDL)
type User {
  id: ID!
  name: String!
  email: String!
  posts: [Post!]!
}

type Post {
  id: ID!
  title: String!
  content: String
  author: User!
}

type Query {
  user(id: ID!): User
  users(limit: Int, offset: Int): [User!]!
  post(id: ID!): Post
}

type Mutation {
  createUser(input: CreateUserInput!): User!
  updateUser(id: ID!, input: UpdateUserInput!): User
  deleteUser(id: ID!): Boolean!
}

input CreateUserInput {
  name: String!
  email: String!
  password: String!
}

type Subscription {
  postCreated: Post!
}
Apollo Server のセットアップ
const { ApolloServer } = require('@apollo/server');
const { expressMiddleware } = require('@apollo/server/express4');
const { readFileSync } = require('fs');

const typeDefs = readFileSync('./schema.graphql', 'utf-8');

const resolvers = {
  Query: {
    user: async (_, { id }, { dataSources }) => {
      return dataSources.userAPI.getUser(id);
    },
    users: async (_, { limit = 10, offset = 0 }, { dataSources }) => {
      return dataSources.userAPI.getUsers(limit, offset);
    }
  },
  Mutation: {
    createUser: async (_, { input }, { dataSources }) => {
      return dataSources.userAPI.createUser(input);
    }
  },
  User: {
    posts: async (parent, _, { dataSources }) => {
      return dataSources.postAPI.getPostsByAuthor(parent.id);
    }
  }
};

const server = new ApolloServer({ typeDefs, resolvers });
await server.start();

app.use('/graphql', express.json(), expressMiddleware(server, {
  context: async ({ req }) => ({
    user: req.user,
    dataSources: {
      userAPI: new UserAPI(),
      postAPI: new PostAPI()
    }
  })
}));

学習ロードマップ

初級(2~3 週間)
  • ✅ GraphQL の概念を理解する
  • ✅ SDL でスキーマを定義する
  • ✅ 基本的なリゾルバーを作成する
  • ✅ クエリとミューテーションの基本を学ぶ
中級(4~6 週間)
  • ✅ フィールドリゾルバーとリレーションシップ
  • ✅ 入力値の検証
  • ✅ エラー処理
  • ✅ N+1 問題に対する DataLoader
上級(8~10 週間)
  • ✅ サブスクリプション(リアルタイム)
  • ✅ 認証と認可
  • ✅ マイクロサービス向けのフェデレーション
  • ✅ パフォーマンスの最適化

N+1 問題に対する DataLoader

const DataLoader = require('dataloader');

const createUserLoader = () =>
  new DataLoader(async (userIds) => {
    const users = await User.find({ _id: { $in: userIds } });
    const userMap = new Map(users.map(u => [u.id, u]));
    return userIds.map(id => userMap.get(id));
  });

// Use in resolver
User: {
  posts: (parent, _, { loaders }) => {
    return loaders.userLoader.load(parent.authorId);
  }
}

認証と認可

const { shield, rule, allow } = require('graphql-shield');

const isAuthenticated = rule()((parent, args, { user }) => {
  return user !== null;
});

const isAdmin = rule()((parent, args, { user }) => {
  return user?.role === 'admin';
});

const permissions = shield({
  Query: { '*': allow, users: isAuthenticated },
  Mutation: {
    createPost: isAuthenticated,
    deleteUser: isAdmin
  }
});

エラー処理

const { ApolloError, UserInputError } = require('apollo-server-express');

class NotFoundError extends ApolloError {
  constructor(message) {
    super(message, 'NOT_FOUND');
  }
}

// In resolvers
const resolvers = {
  Query: {
    user: async (_, { id }) => {
      const user = await User.findById(id);
      if (!user) throw new NotFoundError(`User ${id} not found`);
      return user;
    }
  }
};

ユニットテストのテンプレート

const { createTestClient } = require('apollo-server-testing');

describe('GraphQL API', () => {
  let query, mutate;

  beforeAll(() => {
    const server = new ApolloServer({ typeDefs, resolvers });
    const testClient = createTestClient(server);
    query = testClient.query;
    mutate = testClient.mutate;
  });

  it('should return users list', async () => {
    const GET_USERS = `query { users { id name } }`;
    const res = await query({ query: GET_USERS });

    expect(res.errors).toBeUndefined();
    expect(res.data.users).toBeDefined();
  });
});

トラブルシューティング

問題原因解決策
N+1 クエリの問題フィールドリゾルバーDataLoader を使用する
クエリが遅いキャッシュがないApollo Cache を実装する
型エラースキーマの不一致codegen で検証する
認証の回避ガードがないgraphql-shield を使用する

使用する場面

次のような場合に GraphQL を使用します。

  • クライアントが柔軟なデータ取得を必要とする
  • データのニーズが異なる複数のクライアントがある
  • 過剰なデータ取得やデータ不足を避けたい
  • リアルタイム更新が必要
  • バージョン管理なしで API を進化させたい

関連スキル

  • Express REST API(代替アプローチ)
  • データベース統合(データソース)
  • JWT 認証(API の保護)

リソース

コメント