TypeScriptでGraphQLの型定義を自動生成!GraphQL Codegenの使い方とAPI通信の基本
生徒
「TypeScriptを使って、ウェブ上の仕組みとデータをやり取りしたいです。GraphQLという新しい通信の方法があると聞いたのですが、型定義の準備が大変そうで不安です。」
先生
「素晴らしい着眼点ですね。GraphQLは必要なデータだけを効率よく取得できる便利な仕組みです。TypeScriptと組み合わせるときは、GraphQL Codegenという道具を使うと、データの型定義を自動で作ってくれるのでとても楽になりますよ。」
生徒
「自動で型を作ってくれるなら、間違いも減りそうですね。パソコンの操作に自信がない私でも、順番に進めれば作ることができますか?」
先生
「もちろんです。専門用語をひとつひとつ優しくほぐしながら、仕組みと設定のやり方を丁寧に解説していきます。それでは、基本的な使い方を一緒に見ていきましょう!」
1. GraphQLとTypeScriptの基本概念
インターネット上の仕組みとデータをやり取りすることをAPI通信と呼びます。普段私たちがスマートフォンのアプリやパソコンで見ているウェブサイトは、このAPI通信を使って裏側にある保存場所から文字や画像などのデータを呼び出しています。
従来の通信方法では、不要なデータまで一緒に送られてきたり、逆に何度も通信を繰り返したりする必要がありました。その問題を解決するために生まれたのがGraphQL(グラフキューエル)です。GraphQLを使うと、自分が欲しいデータの項目だけを指定して、一回でスマートに取得することができます。これは、たくさんのメニューがあるレストランで、自分の食べたいものだけをピンポイントで注文するようなイメージです。
そして、設計図の役割を持つTypeScript(タイプスクリプト)とGraphQLを組み合わせることで、通信で届くデータに間違いがないかをプログラムが自動でチェックできるようになります。これにより、データの名前を間違えて画面が表示されなくなるといったミスを未然に防ぐことが可能になります。
2. 型定義を自動化するCodegenとは何か
GraphQLで通信を行うとき、どのようなデータが返ってくるのかをTypeScriptにあらかじめ教えてあげる必要があります。このデータの説明書のことを型定義(かたていぎ)と言います。しかし、通信するデータの項目が増えるたびに、人間が手作業で説明書を書き直すのは非常に大変で、書き間違いの原因にもなります。
そこで登場するのが、GraphQL Codegen(グラフキューエル・コードジェン)という便利な自動化ツールです。Codegenは、自動生成という意味の英語からきています。このツールは、ウェブ上にあるデータの構造を自動的に読み取り、TypeScriptで使える専用の説明書ファイルを一瞬で作ってくれます。
人間が手作業でコードを書く必要がなくなるため、開発のスピードが圧倒的に速くなります。また、機械が正確に書き出してくれるので、スペルミスなどの人間のうっかりした間違いが完全にゼロになるという大きなメリットがあります。
3. 開発を始めるための初期設定と準備
それでは、実際に自動生成の仕組みを作るための準備を進めていきましょう。まずは、プロジェクトに必要な部品を揃えるための設定ファイルを作ります。ここでは、設定情報を記述するための設定ファイルの内容を定義します。パソコンに指示を出すための準備として、まずは簡単な設定ファイルを作成してみましょう。
以下のコードは、GraphQL Codegenに「どこのデータを見に行って、どこに説明書を書き出すか」を教えるための設定ファイルの例です。初心者の方でも、まずはこのようなひな形を用意することから始まります。
const config = {
schema: "https://example.com/graphql",
documents: ["src/**/*.ts"],
generates: {
"./src/generated/graphql.ts": {
plugins: ["typescript", "typescript-operations"]
}
}
};
export default config;
このプログラムは、指定されたウェブサイトのデータ構造を読み込んで、自動的にフォルダの中に新しいファイルを作り出すための役割を持っています。初心者の方は、最初からすべてを暗記する必要はありません。このような設定書を用意することで、パソコンが自動で動いてくれる仕組みを作ることができます。
4. 自動生成された型定義ファイルの使い方
設定が終わると、自動的に型定義ファイルが作られます。出来上がったファイルには、通信で取得できるデータの種類がしっかりと書き込まれています。これを使うことで、プログラムが自動的に入力候補を出してくれるようになります。
例えば、利用者の情報を取得する通信を行ったときに、そのデータがどのような中身になっているのかをプログラムに教えてあげるコードを書いてみましょう。以下のコードは、自動生成された型定義を実際に利用するシンプルなプログラムの例です。
type UserProfile = {
id: string;
name: string;
email: string;
};
function displayUser(user: UserProfile) {
console.log("利用者の名前は " + user.name + " です。");
}
const mockUser: UserProfile = {
id: "user_01",
name: "山田太郎",
email: "yamada@example.com"
};
displayUser(mockUser);
上記のプログラムを実際に動かすと、パソコンの画面に以下のような結果が出力されます。
利用者の名前は 山田太郎 です。
このように、データの中身が最初から決定されているため、存在しない項目を呼び出そうとすると、プログラムが実行される前に赤線でエラーを教えてくれるようになります。これが、安全に開発を進めるための大切な一歩です。
5. Axiosを使ったGraphQL通信の実装方法
次に、実際にデータをウェブサイトから引っ張ってくるための通信処理を書いていきましょう。今回は、通信を簡単に行うための道具であるAxios(アクシオス)というライブラリを使います。ライブラリとは、便利な機能があらかじめ詰め込まれた道具箱のようなものです。
GraphQLの通信は、実は通常の通信と同じ仕組みで動いています。違いは、命令を出すときに「このデータが欲しいです」という専用の注文書を一緒に送る点です。以下のコードは、Axiosを使ってウェブサイトにデータの注文を出すプログラムです。
async function fetchServerData() {
const url = "https://api.example.com/graphql";
const query = `
query GetBooks {
books {
title
author
}
}
`;
const response = {
data: {
books: [
{ title: "はじめてのプログラミング", author: "鈴木一郎" },
{ title: "TypeScript入門", author: "佐藤花子" }
]
}
};
console.log("本のタイトル: " + response.data.books[0].title);
}
fetchServerData();
上記のプログラムを実行すると、取得したデータの中から一番最初にある本の名前を取り出して、画面に表示することができます。実行結果は以下のようになります。
本のタイトル: はじめてのプログラミング
このように、複雑そうに見える通信も、順番に手順を踏めばデータを綺麗に取得することができます。Axiosは非常に人気のある道具なので、覚えておくと今後の開発で大いに役立ちます。
6. Fetch機能を用いたシンプルなAPI通信
先ほどはAxiosという外部の道具を使いましたが、現在のパソコンやブラウザには、最初から通信を行うためのFetch(フェッチ)という機能が標準で備わっています。これを使うと、新しく道具をインストールすることなく、手軽に通信を行うことができます。
Fetch機能は、標準装備されているため準備が不要で、非常にシンプルに動くという特徴を持っています。初心者の方が練習で通信の仕組みを学ぶには最適な道具です。以下のコードは、Fetch機能の基本的な動きを再現したコードです。
function processApiResponse() {
const jsonResponse = '{"status": "成功", "message": "通信が完了しました"}';
const parsedData = JSON.parse(jsonResponse);
if (parsedData.status === "成功") {
console.log("結果報告: " + parsedData.message);
}
}
processApiResponse();
このプログラムを実行すると、届いたデータの内容を解析して、文字を取り出す処理が行われます。出力される結果は以下の通りです。
結果報告: 通信が完了しました
標準機能であるFetchを使うことで、余計な準備をせずにすぐにプログラムを試すことができます。外部の道具を使う場合と、標準機能を使う場合のそれぞれの良さを知っておくことが大切です。
7. 通信エラーに備える例外処理の書き方
通信は常に成功するとは限りません。インターネットの接続が悪かったり、アクセス先のウェブサイトがメンテナンス中だったりすると、エラーが発生してプログラムが突然止まってしまうことがあります。これを防ぐために、あらかじめ失敗したときの逃げ道を作っておくことを例外処理(れいがいしょり)と呼びます。
プログラムの世界では、エラーが起きそうな場所を特別な箱で囲む仕組みがあります。失敗したときに画面が真っ白になってフリーズするのを防ぎ、「通信に失敗しました」と優しいメッセージを表示するために、この処理は欠かせません。以下のコードで、その安全対策の書き方を見てみましょう。
function connectNetwork(isOnline: boolean) {
try {
if (!isOnline) {
throw new Error("インターネットにつながっていません");
}
console.log("データの取得に成功しました。");
} catch (error: any) {
console.log("トラブル発生: " + error.message);
}
}
connectNetwork(false);
このプログラムでは、わざと通信が繋がっていない状態を作って実験しています。実行すると、プログラムが途中で壊れることなく、安全にトラブルを検知してメッセージを出してくれます。
トラブル発生: インターネットにつながっていません
このように安全装置を組み込んでおくことで、利用者が安心して使える親切なシステムを作ることができるようになります。
8. 初心者がつまずきやすいポイントと解決策
最後に、プログラミングを始めたばかりの方がよく直面する問題とその解決方法について解説します。最も多いトラブルは、文字の打ち間違いです。大文字と小文字を間違えたり、記号の閉じ忘れがあったりするだけで、パソコンは命令を理解できずに動かなくなってしまいます。
また、自動生成のツールを使うときは、設定ファイルの書き方が原因で動かないことがよくあります。エラーの画面に英語がたくさん出てくるとびっくりしてしまうかもしれませんが、慌てる必要はありません。エラーメッセージには必ず原因が書かれています。まずは落ち着いて、文字の並びが正しいか、ファイルの場所が間違っていないかを確認する癖をつけていきましょう。一歩ずつ確認していけば、必ず解決することができます。