SPAでAPI設計が重要になる理由とBFF(Backend For Frontend)の役割
SPA開発が難しく感じる最大の理由は、フロントエンドのコード量ではありません。実際には、APIの設計がアプリの使い勝手を直接決めてしまうことにあります。
従来のサーバレンダリングでは、画面はサーバが組み立てていました。しかしSPAでは、画面を組み立てるのはブラウザです。つまり、フロントエンドはAPIから取得したデータだけを材料にして画面を構築します。
この時、APIの形がそのままUIの操作感に影響します。ここがSPA特有の設計難易度の高さです。
サーバレンダリング時代のデータの流れ
SSRやMPAでは、画面表示の流れは単純です。
- ブラウザがURLにアクセス
- サーバがDBから情報を取得
- テンプレートでHTMLを生成
- 完成した画面を返す
テンプレートはサーバ側にあるため、必要な情報はサーバが自由に組み合わせられます。DBテーブル構造が多少不格好でも、テンプレート側で調整できます。
SPAでは何が変わるのか
SPAではテンプレートがブラウザ側に移動します。つまり、サーバはHTMLを返さず、データだけを返します。
GET /api/users/1 { "id": 1, "name": "Taro", "team_id": 5 }
ここで問題が発生します。画面はこのレスポンスをそのまま使って描画する必要があります。もし必要な情報が不足していれば、追加のAPI呼び出しが必要になります。
const user = await fetch("/api/users/1"); const team = await fetch("/api/teams/" + user.team_id);
このようにAPIを連続で呼び出す状態を「N+1リクエスト」に近い形でフロントエンドが抱えることになります。これがSPAのパフォーマンス低下と実装複雑化の原因です。
なぜAPI設計がUIを壊すのか
多くのAPIは、もともとサーバ間通信やモバイルアプリと共有する前提で作られています。そのためDB中心の設計になりがちです。
しかしSPAに必要なのは「テーブル構造」ではなく「画面に必要な情報のまとまり」です。
例えばユーザー一覧画面に必要なのは次です。
- ユーザー名
- 所属チーム名
- アイコンURL
- 最終ログイン
これをテーブル単位APIで取得すると、複数APIを組み合わせる必要が出ます。通信回数が増え、描画が遅れ、ローディング表示が増えます。
つまり、APIがDB設計を反映しているほど、SPAのUXは悪化します。
BFF(Backend For Frontend)とは何か
ここで登場するのがBFFです。
BFFは「フロントエンド専用バックエンド」です。既存APIの前に、UI用のAPI層を追加します。
構成は次のようになります。
- フロントエンド
- BFF
- 既存API(またはマイクロサービス)
- DB
BFFは複数のAPIをまとめ、画面に最適な形で返します。
GET /bff/user-page/1 { "name": "Taro", "team": "Platform", "avatar": "/img/taro.png", "lastLogin": "2024-05-10" }
これによりフロントエンドは1回の通信で画面を描画できます。
BFFが必要になる具体的な場面
BFFが効果を発揮するのは、次のような状況です。
- 画面ごとに必要データが違う
- モバイルとWebでUIが違う
- マイクロサービス化されている
- APIが第三者と共用されている
特にマイクロサービス環境では、フロントエンドが複数サービスに直接アクセスすると通信回数が爆発します。BFFはそれを防ぎます。
GraphQLとの関係
GraphQLは「必要な項目だけ取得する」仕組みですが、BFFと競合するものではありません。むしろBFFの実装手段の一つとして使われます。
違いは役割です。
- GraphQL:取得方法の仕様
- BFF:アーキテクチャの役割
GraphQLだけでは認証統合やレスポンス整形は自動では解決しません。
注意点:BFFは万能ではない
BFFを入れるとサーバが1層増えます。そのため運用コストも増えます。
- デプロイ対象が増える
- キャッシュ設計が必要
- API仕様変更の影響範囲が広がる
小規模サービスでは過剰設計になる場合もあります。APIが単純なCRUDだけなら、直接API呼び出しの方が保守しやすいこともあります。
実際によくある失敗
SPA導入直後に起きやすい問題があります。
- 画面が表示されるまでに複数秒かかる
- ローディングスピナーだらけになる
- フロントエンドのロジックが肥大化する
原因の多くはReactやVueの問題ではありません。APIの粒度です。フロントエンドがデータ結合ロジックを持ち始めると、修正箇所が急増します。
まとめ
SPAでは画面生成がブラウザ側に移るため、APIは単なるデータ提供手段ではなく、UIの一部になります。API設計がそのまま操作体験に直結します。
BFFはそのギャップを埋めるための層です。DB構造を公開するAPIと、画面に必要な情報を返すAPIは目的が違います。ここを分離すると、フロントエンドとバックエンドの責務が整理されます。
SPAの難しさはJavaScriptの複雑さではなく、通信境界の設計にあります。APIを画面の延長として扱えるようになると、実装の安定度は大きく変わります。