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 クライアント層」 を作る。
-
手法:
Axiosやfetchのインスタンスを共通化し、エンドポイントをメソッドとして定義する。 -
コードイメージ:
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) や tRPC 、 rspc を利用する。
-
挙動: 1. バックエンド(Rust 等)が API 定義(スキーマ)を出力する。
-
フロントエンドで
openapi-typescript等のジェネレーターを走らせる。 -
「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 を隠蔽して整理する構成も、大規模開発では非常に有効だよ。
結論
-
環境変数 で環境差分を吸収し、
-
API クライアント層 でエンドポイントを一括管理し、
-
可能なら スキーマ駆動 でクライアントコードを自動生成する。
これが、君の目指す「堅牢な要塞」の標準装備だ!
次は、「実際に 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?