【TypeScript】APIクライアントの型安全な実装方法 - 型安全性を高めるためのベストプラクティス
2024-11-10
2024-11-10
概要
TypeScript
を使ってAPIクライアントを型安全に実装することで、APIレスポンスの構造やリクエストパラメータが保証され、エラーが未然に防止されます。型安全性を確保することで、APIの変更に強く、保守性の高いコードが実現します。本記事では、AxiosやFetch APIを活用したTypeScript
による型安全なAPIクライアントの実装方法を解説し、データフェッチにおけるベストプラクティスを紹介します。
型安全なAPIクライアントの実装方法
APIレスポンスとリクエストパラメータの型定義
まずは、APIレスポンスの型をTypeScript
で定義します。レスポンスのデータ構造がわかっている場合、インターフェースやタイプエイリアスを使って型を定義すると、コードの可読性と安全性が向上します。
例えば、以下のようなユーザー情報を取得するAPIがあるとします。
{
"id": 1,
"name": "Alice",
"email": "alice@example.com"
}
このAPIレスポンスに対応するTypeScript
の型を定義します。
// UserResponse.ts
export interface User {
id: number;
name: string;
email: string;
}
このように、APIのレスポンス型を定義することで、データ取得時に構造が保証され、型安全性が確保されます。
Axiosを使った型安全なAPIクライアント
次に、Axios
を使ってAPIリクエストを行います。AxiosはTypeScript
との相性が良く、型を利用してリクエストとレスポンスの型安全性を確保しやすいライブラリです。
Axiosのインストール
まず、Axiosをインストールします。
npm install axios
Axiosインスタンスの作成
Axiosインスタンスを作成し、リクエストのベースURLや共通設定を行います。
// apiClient.ts
import axios from "axios";
const apiClient = axios.create({
baseURL: "https://api.example.com",
headers: {
"Content-Type": "application/json",
},
});
export default apiClient;
型定義を適用したデータフェッチ
getUser
関数を作成し、先ほど定義したUser
型を使用してレスポンスの型安全性を確保します。
// userService.ts
import apiClient from "./apiClient";
import { User } from "./UserResponse";
export const getUser = async (id: number): Promise<User> => {
const response = await apiClient.get<User>(`/users/${id}`);
return response.data;
};
apiClient.get<User>
のように、レスポンス型を指定することで、response.data
の型がUser
として認識され、型安全なデータ取得が可能になります。
使用例
コンポーネントでgetUser
関数を利用し、型安全にデータを取得します。
import React, { useEffect, useState } from "react";
import { getUser } from "./userService";
import { User } from "./UserResponse";
const UserProfile: React.FC<{ userId: number }> = ({ userId }) => {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
getUser(userId).then(setUser).catch(console.error);
}, [userId]);
if (!user) return <p>Loading...</p>;
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
};
この実装により、APIレスポンスがUser
型に準拠していることが保証され、誤ったデータ構造が返されるとTypeScript
がエラーを検出します。
型安全性を強化するためのライブラリ
TypeScript
での型安全なAPIクライアントの構築に役立ついくつかのライブラリを紹介します。
GraphQL Code Generator
GraphQL Code Generator
は、GraphQLスキーマとクエリからTypeScript
の型を自動生成するツールです。GraphQL APIを利用する際には、GraphQL Code Generatorを使用することで、クエリやレスポンスが自動で型定義され、より安全にGraphQLデータを扱えます。
使用例
GetUser
というクエリから自動生成された型を使うと、以下のように安全なデータ取得が可能です。
import { useGetUserQuery } from "./generated/graphql";
const UserProfile = ({ userId }: { userId: string }) => {
const { data, loading, error } = useGetUserQuery({
variables: { id: userId },
});
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
<h1>{data?.user?.name}</h1>
<p>{data?.user?.email}</p>
</div>
);
};
SWRとReact Query
SWR
とReact Query
は、Reactアプリケーションでのデータフェッチを効率化するライブラリです。APIレスポンスのキャッシュや再取得の管理を自動で行い、APIクライアントにおける型安全性とデータ管理の効率化を同時に実現します。
SWRでの型安全なデータフェッチ
SWRを使用すると、以下のようにデータ取得の型を指定できます。
import useSWR from "swr";
import { User } from "./UserResponse";
import apiClient from "./apiClient";
const fetcher = (url: string) => apiClient.get<User>(url).then((res) => res.data);
const UserProfile = ({ userId }: { userId: number }) => {
const { data: user, error } = useSWR<User>(`/users/${userId}`, fetcher);
if (error) return <p>Error loading user</p>;
if (!user) return <p>Loading...</p>;
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
};
Zodやio-tsを使った実行時の型検証
APIレスポンスの型が確実でない場合、Zod
やio-ts
を使用して実行時の型検証を行い、安全性をさらに高めることができます。
Zodによる型検証
Zodスキーマを作成し、APIレスポンスを検証します。
import { z } from "zod";
import apiClient from "./apiClient";
const userSchema = z.object({
id: z.number(),
name: z.string(),
email: z.string(),
});
type User = z.infer<typeof userSchema>;
export const getUser = async (id: number): Promise<User | null> => {
const response = await apiClient.get(`/users/${id}`);
const result = userSchema.safeParse(response.data);
if (result.success) {
return result.data;
} else {
console.error("Invalid data", result.error);
return null;
}
};
このように、Zodを使ってレスポンスを検証することで、型安全なデータ取得を実現できます。
型安全なAPIクライアント実装のベストプラクティス
- APIレスポンスの型定義を徹底する
APIレスポンスの型をTypeScript
で定義することで、取得するデータ構造が保証され、予期せぬエラーが防止できます。 - リクエストパラメータの型も定義する
リクエストパラメータにも型を定義し、クエリパラメータやリクエストボディの誤りを防ぎましょう。 - 型生成ツールの活用
GraphQL Code GeneratorやOpenAPI Generatorなど、スキーマやAPI仕様から自動で型を生成するツールを活用し、常に最新の型を保持することが重要です。 - 実行時の型検証
APIからのレスポンスの信頼性が確保できない場合、Zodやio-tsを使って実行時にデータの型を検証し、さらに安全性を高めましょう。
まとめ
TypeScript
で型安全なAPIクライアントを実装することにより、APIの構造を保証し、エラーを未然に防ぐことが可能です。AxiosやSWR、React Query、GraphQL Code Generatorといったライブラリやツールを活用することで、APIとの通信が型安全かつ効率的に行えます。APIクライアントの型安全な実装により、開発効率とコードの保守性を向上させましょう。