【TypeScript】PHPとの型定義共有パターン - フロントエンドとバックエンドのデータ整合性を確保

【TypeScript】PHPとの型定義共有パターン - フロントエンドとバックエンドのデータ整合性を確保

2024-10-26

2024-10-26

TypeScriptとPHPの型定義共有の重要性

PHPで構築されたバックエンドAPIと、TypeScriptを用いるフロントエンド間で、データの型定義を一貫させることは、エラー防止とメンテナンス性の向上に非常に重要です。APIレスポンスの構造が変更されても、型定義を共有しておけば、両者のコードが同じデータ構造を前提に動作するため、予期しないバグを防ぐことができます。本記事では、TypeScriptとPHPで型定義を共有するための具体的な戦略を解説します。

PHPとTypeScriptの型定義共有方法

PHPとTypeScript間で型定義を共有するためには、次のアプローチが一般的です:

  1. OpenAPIを用いた型定義の自動生成
    OpenAPI仕様をPHPで定義し、それをもとにTypeScript用の型を自動生成する方法です。
  2. DTOの手動同期
    PHPで定義したDTO(Data Transfer Object)をTypeScriptで再現し、データ構造を統一する方法です。

OpenAPIによる型定義共有の自動化

OpenAPIを使うと、APIエンドポイントの仕様をもとにしたデータ型の自動生成が可能で、PHPとTypeScriptの型定義を共有する際に非常に役立ちます。OpenAPIによって定義されたAPI仕様から、型安全なTypeScriptの型定義やクライアントコードを生成できます。

Step 1: PHPでOpenAPIの設定

PHP環境でAPI仕様を定義するために、zircote/swagger-phpライブラリをインストールし、OpenAPI仕様を生成します。

composer require zircote/swagger-php

次に、APIエンドポイントの仕様をPHPコード上に記述します。

// src/Controllers/UserController.php
namespace App\Controllers;
use App\Models\User;
use OpenApi\Annotations as OA;
class UserController {
    /
     * @OA\Get(
     *     path="/api/users",
     *     summary="Get list of users",
     *     @OA\Response(
     *         response=200,
     *         description="List of users",
     *         @OA\JsonContent(
     *             type="array",
     *             @OA\Items(ref="#/components/schemas/User")
     *         )
     *     )
     * )
     */
    public function index() {
        // ユーザーリストを返す処理
    }
}

Step 2: OpenAPIドキュメントのエクスポート

Swagger CLIを使ってOpenAPIドキュメントをエクスポートします。このドキュメントは、TypeScript用の型定義生成に利用されます。

php vendor/bin/openapi --output openapi.json src

Step 3: TypeScript用の型定義の自動生成

次に、openapi-generator-cliを使用して、エクスポートしたOpenAPIドキュメントからTypeScript用の型を自動生成します。

npm install @openapitools/openapi-generator-cli -g
openapi-generator-cli generate -i openapi.json -g typescript-fetch -o src/api

これにより、TypeScriptの型定義やAPIクライアントが生成され、型安全なデータ操作が可能になります。

DTOの手動同期による型定義共有

OpenAPIを用いず、PHPで定義したDTOとTypeScriptの型定義を手動で同期する方法もあります。DTOを共有することで、フロントエンドとバックエンド間でデータの一貫性が保たれます。

Step 1: PHPでDTOを定義

PHPでAPIレスポンス用のDTOを作成します。例えば、ユーザー情報を表現するUserDTOを以下のように定義します。

// src/DTO/UserDTO.php
namespace App\DTO;
class UserDTO {
    public string $name;
    public string $email;
    public function __construct(string $name, string $email) {
        $this->name = $name;
        $this->email = $email;
    }
}

Step 2: TypeScriptでDTOを再現

TypeScriptで同様の構造を持つDTO型を定義します。これにより、APIレスポンスのデータ構造が変わった場合も、統一したデータ型でデータの操作が可能です。

// types/UserDTO.ts
export interface UserDTO {
  name: string;
  email: string;
}

Step 3: TypeScriptでDTO型を活用

PHPと一致するDTO型をTypeScriptで定義したことで、フロントエンド側でこの型を使用して型安全なデータ操作が可能になります。

// src/api/UserService.ts
import { UserDTO } from "../types/UserDTO";
export const fetchUsers = async (): Promise<UserDTO[]> => {
  const response = await fetch("/api/users");
  return await response.json();
};

型定義共有のメリットと注意点

メリット

  • データの一貫性
    フロントエンドとバックエンドで統一された型を使用することで、データの不整合が発生せず、エラーを防止できます。
  • 保守性の向上
    PHP側で型が変更された場合に、TypeScriptにも自動的に反映されるため、メンテナンスがしやすくなります。
  • 開発効率の向上
    型が共有されていることで、型補完が利用できるため、TypeScriptの開発効率が向上します。

注意点

  • バージョン管理
    型定義のバージョン管理がないと、フロントエンドとバックエンド間で型がずれてエラーが発生する可能性があります。常に型定義の同期を確認しましょう。
  • 自動生成ツールの選定
    プロジェクトの要件に合わせて最適な型生成ツールを選ぶ必要があり、ツールによって生成されるコードや型の構造が異なるため、要件に応じたツールの選定が重要です。

まとめ

TypeScriptとPHPでAPI型定義を共有することにより、データの一貫性が保たれ、予期しないエラーが減少し、保守性と開発効率が向上します。OpenAPIを用いた自動生成やDTOの手動同期を活用し、型の整合性を保ちながら、効率的なアプリケーション開発を実現しましょう。

Recommend