Use Cases

Claude CodeでGraphQL API開発を効率化する方法

Claude Codeを活用してGraphQL APIのスキーマ設計からリゾルバー実装、テストまでを効率的に開発する手法を解説します。

GraphQL開発にClaude Codeが有効な理由

GraphQL APIの開発では、スキーマ定義・リゾルバー実装・型生成・クライアントコードの作成など、多くのファイルを同時に管理する必要があります。Claude Codeはプロジェクト全体を把握した上で、これらを一貫性を持って生成・修正できます。

スキーマ設計を依頼する

> ブログアプリのGraphQLスキーマを設計して。
> User、Post、Comment の3つの型を定義して。
> ページネーションはCursor-basedで実装して。

Claude Codeが生成するスキーマの例です。

type User {
  id: ID!
  name: String!
  email: String!
  posts(first: Int, after: String): PostConnection!
  createdAt: DateTime!
}

type Post {
  id: ID!
  title: String!
  content: String!
  author: User!
  comments(first: Int, after: String): CommentConnection!
  publishedAt: DateTime
  createdAt: DateTime!
}

type Comment {
  id: ID!
  body: String!
  author: User!
  post: Post!
  createdAt: DateTime!
}

type PostConnection {
  edges: [PostEdge!]!
  pageInfo: PageInfo!
}

type PostEdge {
  node: Post!
  cursor: String!
}

type PageInfo {
  hasNextPage: Boolean!
  endCursor: String
}

type Query {
  user(id: ID!): User
  posts(first: Int, after: String): PostConnection!
  post(id: ID!): Post
}

type Mutation {
  createPost(input: CreatePostInput!): Post!
  updatePost(id: ID!, input: UpdatePostInput!): Post!
  deletePost(id: ID!): Boolean!
  addComment(postId: ID!, input: AddCommentInput!): Comment!
}

input CreatePostInput {
  title: String!
  content: String!
}

input UpdatePostInput {
  title: String
  content: String
}

input AddCommentInput {
  body: String!
}

リゾルバーの実装

スキーマが定義できたら、リゾルバーの実装を依頼します。

> 上記スキーマのリゾルバーをTypeScriptで実装して。
> Prismaを使ってDBアクセスして。
> N+1問題を防ぐためにDataLoaderを使って。
import DataLoader from 'dataloader';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

const userLoader = new DataLoader(async (ids: readonly string[]) => {
  const users = await prisma.user.findMany({
    where: { id: { in: [...ids] } },
  });
  const userMap = new Map(users.map(u => [u.id, u]));
  return ids.map(id => userMap.get(id) ?? null);
});

export const resolvers = {
  Query: {
    user: (_: unknown, { id }: { id: string }) =>
      prisma.user.findUnique({ where: { id } }),

    posts: async (_: unknown, { first = 10, after }: { first?: number; after?: string }) => {
      const posts = await prisma.post.findMany({
        take: first + 1,
        ...(after && { cursor: { id: after }, skip: 1 }),
        orderBy: { createdAt: 'desc' },
      });

      const hasNextPage = posts.length > first;
      const edges = posts.slice(0, first).map(post => ({
        node: post,
        cursor: post.id,
      }));

      return {
        edges,
        pageInfo: {
          hasNextPage,
          endCursor: edges[edges.length - 1]?.cursor ?? null,
        },
      };
    },

    post: (_: unknown, { id }: { id: string }) =>
      prisma.post.findUnique({ where: { id } }),
  },

  Post: {
    author: (post: { authorId: string }) => userLoader.load(post.authorId),
  },

  Mutation: {
    createPost: (_: unknown, { input }: { input: { title: string; content: string } }, ctx: { userId: string }) =>
      prisma.post.create({
        data: { ...input, authorId: ctx.userId },
      }),

    deletePost: async (_: unknown, { id }: { id: string }) => {
      await prisma.post.delete({ where: { id } });
      return true;
    },
  },
};

型安全なクライアントコードの生成

> GraphQL Code Generatorの設定を作成して。
> Reactのカスタムフックも自動生成する構成にして。
// codegen.ts
import type { CodegenConfig } from '@graphql-codegen/cli';

const config: CodegenConfig = {
  schema: 'http://localhost:4000/graphql',
  documents: 'src/**/*.graphql',
  generates: {
    'src/generated/graphql.ts': {
      plugins: [
        'typescript',
        'typescript-operations',
        'typescript-react-apollo',
      ],
      config: {
        withHooks: true,
        withComponent: false,
      },
    },
  },
};

export default config;

テストの自動生成

リゾルバーのテストもClaude Codeに任せられます。

> postsクエリとcreatePostミューテーションのテストを書いて。
> テスト用DBにはSQLiteを使って。
import { createTestServer } from './test-utils';

describe('Posts', () => {
  const server = createTestServer();

  it('should fetch paginated posts', async () => {
    const res = await server.executeOperation({
      query: `
        query GetPosts($first: Int) {
          posts(first: $first) {
            edges { node { id title } }
            pageInfo { hasNextPage endCursor }
          }
        }
      `,
      variables: { first: 5 },
    });

    expect(res.body.singleResult.errors).toBeUndefined();
    expect(res.body.singleResult.data?.posts.edges).toHaveLength(5);
  });

  it('should create a post', async () => {
    const res = await server.executeOperation({
      query: `
        mutation CreatePost($input: CreatePostInput!) {
          createPost(input: $input) { id title content }
        }
      `,
      variables: { input: { title: 'Test', content: 'Hello' } },
    });

    expect(res.body.singleResult.data?.createPost.title).toBe('Test');
  });
});

効果的なプロンプトのコツ

GraphQL開発でClaude Codeを使う際のポイントは、スキーマ設計の方針を明確に伝えることです。プロンプトの書き方の詳細はプロンプトテクニック完全ガイドを参照してください。また、プロジェクトのGraphQL規約をCLAUDE.mdに記述しておくと、一貫性の高いコードが得られます。

まとめ

Claude Codeを使えば、GraphQLのスキーマ設計からリゾルバー実装、型生成、テストまでを一貫して効率的に進められます。特にN+1問題への対処やページネーションの実装など、定型的だが間違えやすい部分を正確に生成できるのが強みです。

詳しくはAnthropic公式ドキュメントをご覧ください。GraphQLのベストプラクティスはGraphQL公式サイトも参考になります。

#Claude Code #GraphQL #API開発 #TypeScript #Apollo