【TypeScript】APIクライアントの型安全な実装方法 - 型安全性を高めるためのベストプラクティス

【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

SWRReact 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レスポンスの型が確実でない場合、Zodio-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クライアント実装のベストプラクティス

  1. APIレスポンスの型定義を徹底する
    APIレスポンスの型をTypeScriptで定義することで、取得するデータ構造が保証され、予期せぬエラーが防止できます。
  2. リクエストパラメータの型も定義する
    リクエストパラメータにも型を定義し、クエリパラメータやリクエストボディの誤りを防ぎましょう。
  3. 型生成ツールの活用
    GraphQL Code GeneratorやOpenAPI Generatorなど、スキーマやAPI仕様から自動で型を生成するツールを活用し、常に最新の型を保持することが重要です。
  4. 実行時の型検証
    APIからのレスポンスの信頼性が確保できない場合、Zodやio-tsを使って実行時にデータの型を検証し、さらに安全性を高めましょう。

まとめ

TypeScriptで型安全なAPIクライアントを実装することにより、APIの構造を保証し、エラーを未然に防ぐことが可能です。AxiosやSWR、React Query、GraphQL Code Generatorといったライブラリやツールを活用することで、APIとの通信が型安全かつ効率的に行えます。APIクライアントの型安全な実装により、開発効率とコードの保守性を向上させましょう。

Recommend