Prompt

フロントエンドにAPIへのURLを直書きする代わりに、どうするべき?

フロントエンドにAPIのURLを fetch("https://api.example.com/v1/users") のように直書きするのは、型安全と保守性の観点から「最悪の属人性(誰かがURLを変えたら壊れる)」を生む行為だね。

君が愛する 「一意性」と「SSOT(単一の信頼できる情報源)」 を守るために、プロフェッショナルな現場で取られるアーキテクチャを 3 つのステップで紹介しよう!


1. 環境変数による「ベースURL」の抽象化

まず、ドメインそのものをコードから分離する。

  • 手法: .env ファイルに NEXT_PUBLIC_API_BASE_URL=https://api.example.com と記述する。

  • メリット: 開発環境(localhost)、ステージング、本番環境でコードを一切書き換えずに接続先を切り替えられる。

  • 型安全な工夫: process.env をそのまま使うのではなく、Zod などでバリデーションをかけて 「環境変数が未定義ならビルド時にエラーにする」 設定を CI に組み込むのが「うるさ型」の嗜みだ。


2. API クライアント(SDK)の集約

URL 文字列を各コンポーネントに散らさず、1 箇所に集約した 「API クライアント層」 を作る。

  • 手法: Axiosfetch のインスタンスを共通化し、エンドポイントをメソッドとして定義する。

  • コードイメージ:

    TypeScript

    // services/api.ts
    const client = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_BASE_URL });
    
    export const userResource = {
      get: (id: string) => client.get<User>(`/users/${id}`),
      list: () => client.get<User[]>("/users"),
    };
    
  • メリット: URL の変更が発生した際、修正箇所は常にこのファイル 1 箇所(SSOT)で済む。


3. 【最終形】スキーマからの全自動生成

君が最も好むであろう 「SSOT の聖杯」 だ。URL すら人間が書くのをやめる。

  • 手法: OpenAPI (Swagger)tRPCrspc を利用する。

  • 挙動: 1. バックエンド(Rust 等)が API 定義(スキーマ)を出力する。

    1. フロントエンドで openapi-typescript 等のジェネレーターを走らせる。

    2. 「URL 文字列」ではなく「関数」 として API を呼び出す。

  • 究極の型安全:

    TypeScript

    // URLを書いていないのに、補完が効き、型も付く
    const { data } = useQuery({ queryKey: ['user'], queryFn: () => api.users.get({ id: '123' }) });
    
  • メリット: バックエンドでパスを /v1/users から /v2/members に変えた瞬間、フロントエンドのビルドが通り、パスの整合性が型レベルで保証される。


見落とされがちな視点:マジックナンバーとしての URL

URL の直書きは、プログラミングにおける 「マジックナンバー(意味不明な数値)」 の埋め込みと同じ罪深さがあるんだ。

文章を書かなくても、api.users.get() という関数名があれば、それが「何をするための通信か」という 自己ドキュメント化 になる。これが君の言う「属人性を排した一意性」に繋がるんだね。


豆知識:BFF (Backend For Frontend)

もし API が複雑(複数のマイクロサービスからデータを集める必要があるなど)なら、フロントエンド専用のサーバー(BFF)を Rust などで立て、そこで API URL を隠蔽して整理する構成も、大規模開発では非常に有効だよ。


結論

  1. 環境変数 で環境差分を吸収し、

  2. API クライアント層 でエンドポイントを一括管理し、

  3. 可能なら スキーマ駆動 でクライアントコードを自動生成する。

これが、君の目指す「堅牢な要塞」の標準装備だ!

次は、「実際に OpenAPI から TypeScript の fetch クライアントを自動生成する具体的なワークフロー」 をやってみる?それとも、「Next.js の App Router で環境変数を安全に扱うための server-only パターンの活用」 について深掘りしてみる?

Would you like me to code a sample setup using Zod to validate your environment variables at build time?