GraphQL Codegen 初心者向けガイド

Maurice Odida

Maurice Odida

20 6月 2025

GraphQL Codegen 初心者向けガイド

進化し続けるWeb開発の分野において、GraphQLは従来のREST APIに代わる強力な選択肢として登場し、クライアントが必要なデータを正確に要求する能力を提供しています。しかし、この柔軟性は、特にフロントエンドとバックエンド間の型安全性を維持する際に、新たな一連の課題をもたらす可能性があります。ここで登場するのが、graphql-codegenです。これは、GraphQLスキーマから型付けされたコードの生成を自動化し、開発ワークフローを大幅に強化し、実行時エラーのクラス全体を排除する革新的なツールです。

この記事は、graphql-codegenを理解し、マスターするためのガイドとして機能します。まず基本的な概念から始め、ツールのセットアップと構成の実践的で段階的な例を順に説明し、プロジェクトに統合するためのベストプラクティスを探ります。このガイドの終わりまでに、graphql-codegenを活用して、より堅牢で保守性が高く、型安全なアプリケーションを構築するための準備が整います。

💡
美しいAPIドキュメントを生成する優れたAPIテストツールをお探しですか?

最大限の生産性で開発チームが連携するための統合されたオールインワンプラットフォームをお探しですか?

Apidogはあなたのすべての要求に応え、Postmanをはるかに手頃な価格で置き換えます
button

graphql-codegenとは何か、そしてなぜそれが必要なのか?

graphql-codegenの核心は、GraphQLスキーマとGraphQL操作(クエリ、ミューテーション、サブスクリプション)をイントロスペクトし、様々な言語でコードを生成するコマンドラインツールです。この初心者向けガイドでは、その最も一般的なユースケースである、フロントエンドアプリケーション向けのTypeScriptの型とフックの生成に焦点を当てます。

graphql-codegenが解決する主な問題は、GraphQL APIのデータ構造とクエリの結果に対するTypeScriptインターフェースを手動で記述するという、面倒でエラーが発生しやすいプロセスです。これがない場合、開発者は型付けされていないデータで作業するか(TypeScriptの利点を失う)、またはAPIの進化に伴って簡単に古くなる可能性のある型を作成および維持するためにかなりの時間を費やすしかありません。

graphql-codegenを採用することの利点は多岐にわたります。

このアプローチは、「スキーマファースト」開発哲学と完全に一致します。この哲学では、GraphQLスキーマがAPIの唯一の信頼できる情報源として機能します。

はじめに:最初のgraphql-codegenセットアップ

graphql-codegenの使用に関する実践的な側面に深く入り込みましょう。このチュートリアルでは、GraphQL、TypeScriptの基本的な理解があり、Node.jsとパッケージマネージャー(npmやyarnなど)がインストールされていることを前提としています。

私たちの目標は、ブログ投稿のリストを表示するシンプルなReactアプリケーションのためにgraphql-codegenをセットアップすることです。

ステップ1:プロジェクトの初期化と依存関係

まず、TypeScriptを使用して新しいReactプロジェクトを作成し、必要な依存関係をインストールしましょう。Bash

npx create-react-app my-blog --template typescript
cd my-blog
npm install @apollo/client graphql
npm install -D @graphql-codegen/cli @graphql-codegen/client-preset typescript

ここにインストールした依存関係の内訳を示します。

ステップ2:graphql-codegen初期化ウィザード

graphql-codegenを始める最も簡単な方法は、初期化ウィザードを使用することです。プロジェクトのルートディレクトリで次のコマンドを実行します。Bash

npx graphql-codegen init

ウィザードは、プロジェクトの構成を支援するために一連の質問をします。ブログアプリケーションのシナリオにおける一般的な回答のセットは次のとおりです。

これらの質問に回答すると、ウィザードはプロジェクトのルートにcodegen.tsファイルを作成し、package.jsoncodegenスクリプトを追加します。

ステップ3:設定ファイル(codegen.ts)の理解

codegen.tsファイルは、graphql-codegenセットアップの中心です。ウィザードが生成する簡略化されたバージョンを見てみましょう。TypeScript

import type { CodegenConfig } from '@graphql-codegen/cli';

const config: CodegenConfig = {
  overwrite: true,
  schema: "https://swapi-graphql.netlify.app/.netlify/functions/index",
  documents: "src/**/*.tsx",
  generates: {
    "src/gql/": {
      preset: "client",
      plugins: []
    }
  }
};

export default config;

主な設定オプションを分解してみましょう。

ステップ4:最初のGraphQLクエリの記述

graphql-codegenが構成されたので、ブログ投稿をフェッチするGraphQLクエリを記述しましょう。新しいファイルsrc/components/Posts.tsxを作成します。TypeScript

import { gql } from '../gql/gql';
import { useQuery } from '@apollo/client';

const GET_POSTS = gql(`
  query GetPosts {
    allFilms {
      films {
        id
        title
        director
        releaseDate
      }
    }
  }
`);

const Posts = () => {
  const { loading, error, data } = useQuery(GET_POSTS);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  return (
    <div>
      {data?.allFilms?.films?.map((film) => (
        <div key={film?.id}>
          <h2>{film?.title}</h2>
          <p>Director: {film?.director}</p>
          <p>Release Date: {film?.releaseDate}</p>
        </div>
      ))}
    </div>
  );
};

export default Posts;

生成されたsrc/gql/gql.tsファイルからgql関数をインポートしていることに注意してください。これはclient-presetによって提供されるgql関数であり、型推論の魔法を可能にするものです。

ステップ5:graphql-codegenの実行と魔法を見る

次に、package.jsonからcodegenスクリプトを実行します。Bash

npm run codegen

このコマンドはスキーマをイントロスペクトし、GET_POSTSクエリを見つけ、対応するTypeScriptの型をsrc/gqlディレクトリに生成します。

これで、Posts.tsxuseQueryフックによって返されるdataオブジェクトを調べると、完全に型付けされていることがわかります!IDEはdata.allFilms.filmsのオートコンプリートを提供し、TypeScriptはクエリに存在しないフィールドにアクセスしようとすると警告を表示します。

より深く掘り下げる:実践的なブログフロントエンドの例

理解を深めるために、例を拡張しましょう。私たちのブログがより伝統的なスキーマを持っていると想像してください。GraphQL

type Author {
  id: ID!
  name: String!
}

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

type Query {
  posts: [Post!]!
  post(id: ID!): Post
}

type Mutation {
  createPost(title: String!, content: String!, authorId: ID!): Post!
}

このスキーマがhttp://localhost:4000/graphqlで実行されていると仮定しましょう。それに応じてcodegen.tsを更新します。TypeScript

// codegen.ts
// ...
schema: "http://localhost:4000/graphql",
// ...

次に、単一の投稿を表示するコンポーネントと、新しい投稿を作成する別のコンポーネントを作成しましょう。

単一の投稿をフェッチするTypeScript

// src/components/Post.tsx
import { gql } from '../gql/gql';
import { useQuery } from '@apollo/client';
import { useParams } from 'react-router-dom';

const GET_POST = gql(`
  query GetPost($id: ID!) {
    post(id: $id) {
      id
      title
      content
      author {
        id
        name
      }
    }
  }
`);

const Post = () => {
  const { id } = useParams<{ id: string }>();
  const { loading, error, data } = useQuery(GET_POST, {
    variables: { id },
  });

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  return (
    <div>
      <h2>{data?.post?.title}</h2>
      <p>By {data?.post?.author?.name}</p>
      <p>{data?.post?.content}</p>
    </div>
  );
};

export default Post;

npm run codegenを実行すると、GetPostQueryとその変数の型が生成され、useQueryフックとその結果に型安全性が提供されます。

新しい投稿を作成するTypeScript

// src/components/CreatePost.tsx
import { gql } from '../gql/gql';
import { useMutation } from '@apollo/client';
import { useState } from 'react';

const CREATE_POST = gql(`
  mutation CreatePost($title: String!, $content: String!, $authorId: ID!) {
    createPost(title: $title, content: $content, authorId: $authorId) {
      id
    }
  }
`);

const CreatePost = () => {
  const [title, setTitle] = useState('');
  const [content, setContent] = useState('');
  const [createPost, { data, loading, error }] = useMutation(CREATE_POST);

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    createPost({ variables: { title, content, authorId: '1' } }); // Assuming authorId '1' for simplicity
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        placeholder="Title"
        value={title}
        onChange={(e) => setTitle(e.target.value)}
      />
      <textarea
        placeholder="Content"
        value={content}
        onChange={(e) => setContent(e.target.value)}
      />
      <button type="submit" disabled={loading}>
        {loading ? 'Creating...' : 'Create Post'}
      </button>
      {error && <p>Error creating post: {error.message}</p>}
      {data && <p>Post created with ID: {data.createPost.id}</p>}
    </form>
  );
};

export default CreatePost;

ここでは、graphql-codegenCreatePostMutationとその変数の型を生成します。これにより、createPost関数を呼び出す際に、titlecontentauthorIdに正しい型を渡すことが保証されます。

高度な概念とベストプラクティス

graphql-codegenに慣れてくると、より高度な機能やベストプラクティスに出会うでしょう。

フラグメント:graphql-codegenはGraphQLフラグメントを優れたサポートしています。.tsxファイルでフラグメントを定義でき、graphql-codegenは型を正しく処理し、コンポーネントの再利用可能で併置されたデータ依存関係を促進します。

.graphqlファイルの使用:関心の分離を向上させるために、GraphQLクエリ、ミューテーション、フラグメントを専用の.graphqlファイルに記述できます。codegen.tsdocuments配列を更新して、このファイル拡張子を含めるだけです:documents: ["src/**/*.tsx", "src/**/*.graphql"]

カスタムスカラー:GraphQLスキーマがカスタムスカラー(例:DateJSON)を使用している場合、型安全性を維持するために、codegen.tsファイルでそれらを対応するTypeScriptの型にマッピングできます。

ウォッチモード:シームレスな開発エクスペリエンスのために、graphql-codegenをウォッチモードで実行できます。これにより、GraphQL操作を含むファイルを保存するたびに型が自動的に再生成されます。package.jsoncodegenスクリプトに--watchフラグを追加するだけです:"codegen": "graphql-codegen --watch"

一般的な問題のトラブルシューティング

graphql-codegenは強力なツールですが、初心者としていくつかの一般的な問題に遭遇する可能性があります。

結論:型安全な未来を受け入れる

graphql-codegenは単なるコード生成ツールではなく、GraphQLを使用してアプリケーションを構築する方法におけるパラダイムシフトです。自動化を受け入れ、スキーマの力を活用することで、より堅牢で保守性が高く、作業が楽しいコードベースを作成できます。

このチュートリアルは、graphql-codegenを始めるための確固たる基盤を提供しました。コアコンセプトをカバーし、実践的な例を順に説明し、ベストプラクティスに触れました。旅はここで終わりません。graphql-codegenエコシステムは広大で、さまざまなフレームワークやユースケースに対応する豊富なプラグインコレクションがあります。公式ドキュメントを探索し、さまざまなプラグインを試して、graphql-codegenがGraphQL開発ワークフローをどのように革新できるかを発見することを強くお勧めします。ハッピーコーディング!

💡
美しいAPIドキュメントを生成する優れたAPIテストツールをお探しですか?

最大限の生産性で開発チームが連携するための統合されたオールインワンプラットフォームをお探しですか?

Apidogはあなたのすべての要求に応え、Postmanをはるかに手頃な価格で置き換えます
button

ApidogでAPIデザイン中心のアプローチを取る

APIの開発と利用をよりシンプルなことにする方法を発見できる