Prompt
バックエンドAPIがフロントエンドのどこから参照・呼び出しされているか追跡しづらい問題をどうする?
その悩み、フロントエンドとバックエンドが疎結合になりすぎたがゆえに起きる、モダン開発における 「情報の断絶」 だね。
APIのパスを文字列で管理していると、バックエンドでエンドポイント名を少し変えただけでフロントが沈黙し、どこで使われているか grep で探す羽目になる。これは君が最も嫌う 「一意性の欠如」 と 「属人性への依存」 そのものだ。
この「追跡不能問題」を論理的・構造的に解決するための 3 つの階層的なアプローチを提案しよう。
1. 型による「静的」な結合(開発時の追跡)
「どこで使われているか」を検索するのではなく、「型が繋がっているから、IDEが教えてくれる」 状態を作るのが正攻法だ。
OpenAPI + Client SDK 生成
バックエンドが唯一の真実(SSOT)となる OpenAPI 仕様書を出し、フロントエンドはそこから 「関数」 を自動生成する。
-
解決策:
openapi-generatorやaspidaを使う。 -
効果: API の呼び出しが
axios.get('/api/v1/user')ではなくapi.user.get()という関数呼び出しになる。IDE の 「参照へジャンプ」 機能で、プロジェクト内のどこでその API が呼ばれているか一瞬でリストアップできるよ。
tRPC (TypeScript の場合)
バックエンドの関数定義を直接フロントでインポートする。
- 効果: バックエンドの関数名をリファクタリング(名前変更)すれば、フロントの全呼び出し箇所も IDE が一斉に直してくれる。追跡する必要すらなく、「常に同期している」 状態になるんだ。
2. ヘッダーによる「動的」な追跡(実行時の追跡)
本番環境で「このリクエストはどの画面のどのボタンから来たのか」を特定したい場合、HTTP ヘッダーに 「文脈(Context)」 を乗せる手法が有効だ。
オリエンテーション・ヘッダー
フロントエンドの各リクエストに、呼び出し元のコンポーネント名やページ ID を付与する。
-
例:
X-App-Source: UserProfilePage/FollowButton -
効果: バックエンドのログを見れば、「この API はプロフィール画面のフォローボタンから頻繁に叩かれている」という事実が一目瞭然になる。
トレース ID (Distributed Tracing)
OpenTelemetry を使い、フロントエンドからバックエンド、さらにはその先の DB まで 「一意なリクエスト ID」 を引き継ぐ。
- 効果: 障害が起きたとき、フロントの特定操作からバックエンドのどの処理が走ったかを、一続きのタイムラインとして可視化できる。
3. スキーマによる「依存関係」の可視化
API そのものではなく、「データ項目(フィールド)」 単位で追跡したいなら、GraphQL が最強の武器になる。
-
GraphQL の
Apollo Studioなど: * どのフィールドが、どのフロントエンド(iOS, Web)から、どの程度の頻度でリクエストされているかをグラフ化してくれる。 -
効果: 「この
ageというフィールド、実はもうどこのフロントからも呼ばれていないから削除していい」といった判断が、推測ではなく 「データ」 に基づいて行えるようになる。
見落とされがちな視点:ドキュメントとしての「コード」
君が公開しているデジタルガーデン(https://garden.asappy.xyz)の考え方と同じで、コードも 「それ自体が説明不要な地図」 であるべきだ。
API のエンドポイントを constants/api.ts のような場所に一括で定義せず、「API 呼び出しを抽象化した Service 層(あるいは Hooks 層)」 を作り、そこを起点に追跡できる構造にすること。
「文字列(URL)」という曖昧な情報を、「シンボル(関数)」という一意な情報に変換する。これが、追跡不能の迷宮から抜け出すための唯一の道だよ。
結論
-
静的追跡: SDK 生成や tRPC で、IDE の「参照元を探す」機能を使えるようにする。
-
動的追跡: 独自の HTTP ヘッダーやトレース ID を仕込み、ログから「犯人(呼び出し元)」を特定できるようにする。
まずは、「OpenAPI から TypeScript のクライアントコードを自動生成して、IDE で『右クリック → 参照元を検索』ができる環境」 を作ってみるのはどうかな?
Would you like me to code a sample script that generates a type-safe API client from an OpenAPI spec and shows how to use it in a React component?