進化し続けるWeb開発の分野において、GraphQLは従来のREST APIに代わる強力な選択肢として登場し、クライアントが必要なデータを正確に要求する能力を提供しています。しかし、この柔軟性は、特にフロントエンドとバックエンド間の型安全性を維持する際に、新たな一連の課題をもたらす可能性があります。ここで登場するのが、graphql-codegen
です。これは、GraphQLスキーマから型付けされたコードの生成を自動化し、開発ワークフローを大幅に強化し、実行時エラーのクラス全体を排除する革新的なツールです。
この記事は、graphql-codegen
を理解し、マスターするためのガイドとして機能します。まず基本的な概念から始め、ツールのセットアップと構成の実践的で段階的な例を順に説明し、プロジェクトに統合するためのベストプラクティスを探ります。このガイドの終わりまでに、graphql-codegen
を活用して、より堅牢で保守性が高く、型安全なアプリケーションを構築するための準備が整います。
最大限の生産性で開発チームが連携するための統合されたオールインワンプラットフォームをお探しですか?
Apidogはあなたのすべての要求に応え、Postmanをはるかに手頃な価格で置き換えます!
graphql-codegen
とは何か、そしてなぜそれが必要なのか?
graphql-codegen
の核心は、GraphQLスキーマとGraphQL操作(クエリ、ミューテーション、サブスクリプション)をイントロスペクトし、様々な言語でコードを生成するコマンドラインツールです。この初心者向けガイドでは、その最も一般的なユースケースである、フロントエンドアプリケーション向けのTypeScriptの型とフックの生成に焦点を当てます。
graphql-codegen
が解決する主な問題は、GraphQL APIのデータ構造とクエリの結果に対するTypeScriptインターフェースを手動で記述するという、面倒でエラーが発生しやすいプロセスです。これがない場合、開発者は型付けされていないデータで作業するか(TypeScriptの利点を失う)、またはAPIの進化に伴って簡単に古くなる可能性のある型を作成および維持するためにかなりの時間を費やすしかありません。
graphql-codegen
を採用することの利点は多岐にわたります。
- エンドツーエンドの型安全性:スキーマから直接型を生成することで、
graphql-codegen
はフロントエンドコードがバックエンドのデータモデルと常に同期していることを保証します。これは、型関連のエラーを実行時ではなく、コンパイル時に捕捉できることを意味します。 - 開発者エクスペリエンスの向上:生成された型を使用すると、コードエディタでのオートコンプリートやインテリジェントな提案などの機能が利用でき、開発がより迅速かつ効率的になります。APIレスポンスの形状を推測する必要はもうありません!
- ボイラープレートの削減:
graphql-codegen
は、型だけでなく、Apollo ClientやReact Queryのような一般的なGraphQLクライアント向けのすぐに使えるフックも生成できます。これにより、繰り返し発生するデータフェッチロジックを記述する必要がなくなります。 - 保守性の向上:APIスキーマが変更された場合、型を再生成するために必要なのは簡単なコマンドだけです。これにより、コードベースの保守とリファクタリングが時間とともに大幅に容易になります。
このアプローチは、「スキーマファースト」開発哲学と完全に一致します。この哲学では、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
ここにインストールした依存関係の内訳を示します。
@apollo/client
:React用の一般的なGraphQLクライアント。graphql
:Apollo Clientとgraphql-codegen
の両方に必要なピア依存関係。@graphql-codegen/cli
:graphql-codegen
のコマンドラインインターフェース。@graphql-codegen/client-preset
:クライアントサイドアプリケーションの構成を簡素化するモダンで合理化されたプリセット。typescript
:TypeScriptコンパイラ。
ステップ2:graphql-codegen
初期化ウィザード
graphql-codegen
を始める最も簡単な方法は、初期化ウィザードを使用することです。プロジェクトのルートディレクトリで次のコマンドを実行します。Bash
npx graphql-codegen init
ウィザードは、プロジェクトの構成を支援するために一連の質問をします。ブログアプリケーションのシナリオにおける一般的な回答のセットは次のとおりです。
- どのような種類のアプリケーションを構築していますか?
Application built with React
- スキーマはどこにありますか? GraphQL APIエンドポイントのURLを提供します。このチュートリアルでは、公開されているサンプルAPIを使用できます:
https://swapi-graphql.netlify.app/.netlify/functions/index
- 操作とフラグメントはどこにありますか?
src/**/*.tsx
(これは、src
ディレクトリ内のすべての.tsx
ファイルでGraphQLクエリを探すようにgraphql-codegen
に指示します)。 - プラグインを選択してください:ウィザードは一連のプラグインを提案します。
typescript
、typescript-operations
、typescript-react-apollo
を含むデフォルトは素晴らしい出発点です。 - 出力をどこに書き込みますか?
src/gql/
(これにより、生成されたファイルを保存するための新しいディレクトリsrc/gql
が作成されます)。 - イントロスペクションファイルを生成しますか?
Yes
(これはローカル開発やIDE拡張機能に役立ちます)。 - 設定ファイルの名前は何にしますか?
codegen.ts
- package.jsonのどのスクリプトでcodegenを実行しますか?
codegen
これらの質問に回答すると、ウィザードはプロジェクトのルートにcodegen.ts
ファイルを作成し、package.json
にcodegen
スクリプトを追加します。
ステップ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;
主な設定オプションを分解してみましょう。
overwrite: true
:これにより、コマンドを実行するたびに既存の生成済みファイルが上書きされることが保証されます。schema
:これはGraphQLスキーマのソースを指します。ライブエンドポイントのURL、ローカルの.graphql
または.json
ファイルなどが指定できます。documents
:これは、GraphQL操作(クエリ、ミューテーション、フラグメント)を見つける場所をgraphql-codegen
に伝えるグロブパターンです。generates
:これは構成の最も重要な部分です。各キーが出力ファイルまたはディレクトリを表し、値が何を生成するかを定義するオブジェクトです。preset: "client"
:client-preset
は、フロントエンドアプリケーション向けにgraphql-codegen
を構成するための強力で推奨される方法です。いくつかのプラグインをバンドルし、合理化されたエクスペリエンスを提供します。クエリを記述するために使用するgraphql
関数を生成します。
ステップ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.tsx
のuseQuery
フックによって返される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-codegen
がCreatePostMutation
とその変数の型を生成します。これにより、createPost
関数を呼び出す際に、title
、content
、authorId
に正しい型を渡すことが保証されます。
高度な概念とベストプラクティス
graphql-codegen
に慣れてくると、より高度な機能やベストプラクティスに出会うでしょう。
フラグメント:graphql-codegen
はGraphQLフラグメントを優れたサポートしています。.tsx
ファイルでフラグメントを定義でき、graphql-codegen
は型を正しく処理し、コンポーネントの再利用可能で併置されたデータ依存関係を促進します。
.graphql
ファイルの使用:関心の分離を向上させるために、GraphQLクエリ、ミューテーション、フラグメントを専用の.graphql
ファイルに記述できます。codegen.ts
のdocuments
配列を更新して、このファイル拡張子を含めるだけです:documents: ["src/**/*.tsx", "src/**/*.graphql"]
。
カスタムスカラー:GraphQLスキーマがカスタムスカラー(例:Date
、JSON
)を使用している場合、型安全性を維持するために、codegen.ts
ファイルでそれらを対応するTypeScriptの型にマッピングできます。
ウォッチモード:シームレスな開発エクスペリエンスのために、graphql-codegen
をウォッチモードで実行できます。これにより、GraphQL操作を含むファイルを保存するたびに型が自動的に再生成されます。package.json
のcodegen
スクリプトに--watch
フラグを追加するだけです:"codegen": "graphql-codegen --watch"
。
一般的な問題のトラブルシューティング
graphql-codegen
は強力なツールですが、初心者としていくつかの一般的な問題に遭遇する可能性があります。
- 「スキーマが見つかりません」:このエラーは通常、
codegen.ts
のschema
パスが間違っているか、指定されたアドレスでGraphQLサーバーが実行されていないことを意味します。 - プラグイン構成エラー:必要なすべてのプラグインがインストールされていること、および
codegen.ts
での構成が正しいことを確認してください。 graphql
ピア依存関係の問題:プロジェクトにgraphql
が直接依存関係としてインストールされていることを確認してください。
結論:型安全な未来を受け入れる
graphql-codegen
は単なるコード生成ツールではなく、GraphQLを使用してアプリケーションを構築する方法におけるパラダイムシフトです。自動化を受け入れ、スキーマの力を活用することで、より堅牢で保守性が高く、作業が楽しいコードベースを作成できます。
このチュートリアルは、graphql-codegen
を始めるための確固たる基盤を提供しました。コアコンセプトをカバーし、実践的な例を順に説明し、ベストプラクティスに触れました。旅はここで終わりません。graphql-codegen
エコシステムは広大で、さまざまなフレームワークやユースケースに対応する豊富なプラグインコレクションがあります。公式ドキュメントを探索し、さまざまなプラグインを試して、graphql-codegen
がGraphQL開発ワークフローをどのように革新できるかを発見することを強くお勧めします。ハッピーコーディング!
最大限の生産性で開発チームが連携するための統合されたオールインワンプラットフォームをお探しですか?
Apidogはあなたのすべての要求に応え、Postmanをはるかに手頃な価格で置き換えます!