ひとことで言うと#
モバイルアプリ、Webアプリ、サードパーティなど、クライアントの種類ごとに専用のバックエンド(BFF)を設けるパターン。汎用的な1つのAPIですべてのクライアントに対応するのではなく、各フロントエンドに最適化されたAPIを提供する。
押さえておきたい用語#
- BFF(Backend for Frontend)
- フロントエンドの種類(Web、モバイル等)ごとに設ける専用のバックエンドサーバー。API翻訳層として機能する。
- API集約(API Aggregation)
- 複数のマイクロサービスからデータを取得し、1つのレスポンスにまとめて返すこと。BFFの主要な役割の一つ。
- オーバーフェッチング
- クライアントが必要としない余分なデータまでAPIが返してしまう問題を指す。通信量とパース時間の無駄が生じる。
- アンダーフェッチング
- 1回のAPI呼び出しでは足りず、複数回のリクエストが必要になる問題である。画面表示の遅延を招く。
- API翻訳層
- 下流サービスのレスポンスをフロントエンドが使いやすい形に変換するレイヤー。BFFの本質的な役割。
BFFパターンの全体像#
こんな悩みに効く#
- モバイルアプリに不要なデータまでAPIが返していて、通信量が無駄に多い
- Webとモバイルで必要なデータが異なるのに、1つのAPIで無理に対応している
- フロントエンドの変更のたびにバックエンドAPIの修正が必要になる
基本の使い方#
BFFはすべてのプロジェクトに必要なわけではない。導入すべき状況を見極める。
- BFFが有効: クライアントが複数種類(Web、モバイル、IoT)あり、それぞれ必要なデータや画面構成が大きく異なる
- BFF不要: クライアントが1種類のみ、またはクライアント間のAPI要件がほぼ同じ
- 代替手段: GraphQLで各クライアントが必要なデータだけ取得する方式も検討
ポイント: クライアントが1種類なら、BFFは過剰設計。シンプルなAPIで十分。
BFFが何をして、何をしないかを定義する。
- BFFの責務: レスポンスの集約・整形、クライアント固有の認証、フロントエンド用のデータ変換
- BFFに置かないもの: ビジネスロジック、データバリデーション、永続化処理
- BFFは「フロントエンドのためのAPI翻訳層」であり、ビジネスロジックは下流のサービスに任せる
ポイント: BFFにビジネスロジックを入れると、ロジックの重複やBFF肥大化を招く。薄く保つこと。
各クライアントの画面構成とデータ要件に合わせてBFFを設計する。
- Web BFF: ページ単位で必要なデータを一括取得するエンドポイント
- Mobile BFF: 帯域を考慮して最小限のデータを返す。ページネーションを積極的に活用
- Third-party BFF: 安定したバージョニングとレート制限を備えた公開API
ポイント: 1つのBFFが複数クライアントを担当しない。そうするとBFFを導入した意味がなくなる。
BFFを誰が開発・保守するかを明確にする。
- フロントエンドチームがBFFも開発する(推奨)。UIの要件変更に即座に対応できる
- バックエンドチームに依頼する運用だと、コミュニケーションコストが発生する
- BFFの技術スタックはフロントエンドチームが扱いやすいもの(Node.js等)を選ぶと良い
ポイント: **「UIを知っている人がBFFを書く」**のが、最も効率的な開発体制。
具体例#
状況: 旅行予約サービスの汎用API。Webの検索結果画面は詳細情報(写真10枚、口コミ5件)を表示、モバイルは一覧性重視(写真1枚、星評価のみ)。1つのAPIですべて返しており、モバイルで不要なデータを大量に送信していた。
BFF分離:
- Web BFF (
/web-bff/search): ホテル情報+写真10枚+口コミ5件+周辺施設 → 1レスポンス約15KB - Mobile BFF (
/mobile-bff/search): ホテル名+写真1枚+星評価+料金 → 1レスポンス約2KB - 両BFFとも下流の同じマイクロサービス(ホテルサービス、口コミサービス)を呼び出す
モバイルアプリのレスポンスサイズが87%削減(15KB→2KB)。ページ読み込み速度が1.8秒→0.5秒に改善し、フロントエンドチームがBFFを自由に変更でき、バックエンドへの依頼待ちがゼロになった。
状況: Webとモバイルアプリが同じ汎用APIを使用。商品詳細ページの改修で、フロントエンドチームがバックエンドチームにAPI変更を依頼 → レビュー → 実装 → デプロイ待ちで平均10日。
施策:
- Node.js(TypeScript)でWeb BFFとMobile BFFを構築
- 各BFFのオーナーシップをフロントエンドチーム(各3名)に移管
- BFFは集約・整形のみ。価格計算や在庫チェックは下流サービスが担当
BFF導入の最大の効果は「待ち時間の解消」だった。フロントエンドの機能改修リードタイムが平均10日→4日に短縮され、バックエンドチームもAPIの汎用性を気にせずドメインロジックに集中できるようになった。
状況: IoTプラットフォーム。デバイス(数バイトの軽量JSON)、管理ダッシュボード(グラフ描画用の集計データ)、パートナーAPI(安定したバージョニング付き)の3クライアントが同一APIを共有。
BFF設計:
- Device BFF: レスポンス100バイト以下。プロトコルバッファ対応。レイテンシ50ms以下
- Dashboard BFF: 時系列データを1時間・1日・1週間単位で集計して返す
- Partner BFF: REST + OpenAPI。バージョニングとレート制限(1000 req/min)付き
デバイスのバッテリー消費が23%改善(通信データ量削減による)。ダッシュボードの初期表示は4.2秒→1.1秒に改善し、パートナーからのAPI関連問い合わせも月30件→5件に減少した。
やりがちな失敗パターン#
- BFFにビジネスロジックを入れてしまう — 注文バリデーションや価格計算をBFFに書くと、WebとモバイルのBFFでロジック重複が発生する。ビジネスロジックは下流サービスに集約する
- BFFが単なるプロキシになる — バックエンドのレスポンスをそのまま転送するだけならBFFの意味がない。データの集約・整形という価値を提供すること
- BFFの数を増やしすぎる — クライアント種類が増えるたびにBFFを増やすと保守が大変。本当にAPI要件が異なるクライアントだけにBFFを設ける
- BFFのオーナーシップが曖昧 — フロントエンドとバックエンドの両方が「相手の仕事」と思い、誰も面倒を見ない。BFFのオーナーを明確に定め、PRのアサインルールまで決める
まとめ#
BFFパターンは、複数の異なるフロントエンドに対して最適なAPIを提供するための設計パターン。汎用APIの 「誰にとっても微妙」 な問題を解決し、各クライアントに必要十分なデータを効率的に届ける。BFFは薄く保ち、ビジネスロジックは下流に任せ、フロントエンドチームがオーナーシップを持つのが成功の方程式だ。