08
第 8 章

BFF の要否と構成の選び方

この章で学ぶこと
1 そもそも BFF が不要な条件
2 フルスタックフレームワークで BFF 相当の処理を書く方法
3 フルスタックフレームワークでは足りなくなり独立サービスとして構築する条件
4 3 つの選択肢の判断基準
解説

BFF はどのように構築されるか

実体は通常のサーバサイドアプリケーション
BFF 専用の製品があるわけではなく、Web フレームワークで API サーバとして実装する
Node.js 系フレームワークが主流
Express・NestJS・Fastify など。フロントエンドと同じ TypeScript で書ける
フロントエンドフレームワークのサーバサイド機能で作る構成も普及
Next.js などはプロジェクト内に API エンドポイントを実装できる
3 つの選択肢
① BFF 不要
② フルスタックFW
③ 独立サービス
比較と判断
まとめ
解説

Next.js の Route Handler で BFF を作る

Route Handler(App Router の機能)
app/api/dashboard/route.ts を置くと /api/dashboard が HTTP エンドポイントになる
Pages Router では pages/api/ の API Routes が同等の機能
サーバサイドで実行される
ブラウザには送られない。バックエンド API の呼び出しやトークン管理をここに書ける
フロントエンド一体型 BFF
Route Handler を使ってフロントエンドと同じプロジェクト内に BFF 相当の API を実装する構成(本講座での呼び方)
3 つの選択肢
① BFF 不要
② フルスタックFW
③ 独立サービス
比較と判断
まとめ
コード

Route Handler の集約コード

Promise.all で並列呼び出し
ユーザーサービスと注文サービスを同時に呼び出し、結果を 1 つの JSON に集約
ch08-decision-framework/src/app/api/dashboard/route.ts
お手元のエディタでお開きください
3 つの選択肢
① BFF 不要
② フルスタックFW
③ 独立サービス
比較と判断
まとめ
図解

Next.js デプロイ時の構成

Next.js の 1 つのビルド成果物がフロントエンド資材の配信と Route Handler の API 機能を兼ねる

クライアント
ブラウザ
画面の取得と API 呼び出しを同じサーバに送る
Next.js サーバ
1 つのデプロイ単位/2 つの役割
同一プロセス・同一ポート
フロントエンド資材の配信
HTML / CSS / JS
Route Handler(BFF 相当の処理)
/api/dashboard — 集約・整形・認証
バックエンド API
ユーザーサービス
注文サービス
ビルド単位は常に一体。自前サーバでは同一プロセス・同一ポートで動作する
3 つの選択肢
① BFF 不要
② フルスタックFW
③ 独立サービス
比較と判断
まとめ
解説

フルスタックフレームワークとコロケーション

フルスタックフレームワーク
フロントエンドの画面開発とサーバサイドの API 開発を、1 つのフレームワーク・1 つのプロジェクトで行える開発基盤。Next.js・Nuxt・SvelteKit・Remix などが該当する
コロケーション
関連するコードを同じ場所にまとめる設計方針。フルスタックフレームワークでは、ある画面のコンポーネントとその画面が必要とする API エンドポイントを同じディレクトリに配置できる
BFF 相当の処理をフロントエンドと同居させられる
集約・整形・認証仲介のコードをフロントエンドのプロジェクト内に書ける
3 つの選択肢
① BFF 不要
② フルスタックFW
③ 独立サービス
比較と判断
まとめ
解説

3 つの選択肢

フロントエンドの技術スタックとプロジェクトの要件に応じて選ぶ、独立した 3 つの選択肢

1
BFF を使わない
バックエンド API が 1 つで、フロントエンドが直接呼べば足りる
2
フルスタックフレームワークでフロントエンドと一緒に開発
フルスタックフレームワークを使用している場合の選択肢。集約や認証仲介が必要だが、プロジェクト内に収まる規模
3
独立サービスとして構築する
フロントエンドの技術スタックを問わない。複数クライアント対応やチーム分離など、プロジェクト内では収まらない要件がある
番号は優劣ではなく、フロントエンドの技術スタックとプロジェクトの要件に応じて選ぶ観点の違い
3 つの選択肢
① BFF 不要
② フルスタックFW
③ 独立サービス
比較と判断
まとめ
解説

① BFF を使わない判断

3 つすべてが当てはまるなら、フロントエンドから直接 API を呼べば足りる

API を集約する必要性がない
たとえば 1 画面に対して 1 つの API で概ね済む構成
レスポンスの整形が不要
API の返すデータ構造がフロントエンドの表示にそのまま使える
認証の仲介が不要
バックエンド API が認証を直接管理しており、トークンを BFF で中継する動機がない
この状態で BFF を挟むと、コードとインフラだけが増える
3 つの選択肢
① BFF 不要
② フルスタックFW
③ 独立サービス
比較と判断
まとめ
解説

② フルスタックフレームワークで書く判断

集約が必要になっても、この 3 条件が続く限りサービスを増やさない

前提:フルスタックフレームワークを使用している
フロントエンドと同居した BFF はフルスタックフレームワークの機能なので、フルスタックフレームワークを使用していることが前提になる
レスポンスの出し分けが不要
クライアントが Web だけなら、同じ形で返せばよい
デプロイ単位を分ける動機がない
たとえば同じチームがフロントと BFF を管理しており、リリースサイクルが同じ
集約ロジックが小規模
たとえば 2〜3 個のバックエンド API を Promise.all で束ねる程度
この段階で ③ へ進むと、ビルド・監視・ネットワークの運用負荷だけが増える
3 つの選択肢
① BFF 不要
② フルスタックFW
③ 独立サービス
比較と判断
まとめ
解説

③ 独立サービスとして構築する判断要素

独立サービスとして構築するかどうかを判断する 判断要素

レスポンスの出し分けが必要
たとえば Web とモバイルで返すデータ構造が異なり、フルスタックフレームワーク側の実装内の if 分岐が増えている
集約の複雑さが収まらない
たとえばバックエンド API が 5 つ以上に増え、縮退分岐やリトライが各サービスにある状態
3 つの選択肢
① BFF 不要
② フルスタックFW
③ 独立サービス
比較と判断
まとめ
解説

③ 独立サービスとして構築する判断要素

いずれかに該当すれば独立サービスとして構築し、該当しなければフルスタックフレームワークに留まる

チームの所有権と独立デプロイが必要
一方の変更が他方のデプロイをブロックする状態
セキュリティ境界の明確な分離
トークン管理をプロセスレベルで分離したい場合
3 つの選択肢
① BFF 不要
② フルスタックFW
③ 独立サービス
比較と判断
まとめ
図解

3 つの選択肢の判断フロー

集約の必要性、フロントエンドがフルスタックフレームワークかどうか、3 つの条件で判断する

3 つの選択肢
① BFF 不要
② フルスタックFW
③ 独立サービス
比較と判断
まとめ
まとめ

この章のまとめ

BFF を使うかどうかは 3 つの選択肢から判断する
バックエンド API が 1 つで集約も整形も不要なら BFF は不要
フロントエンドがフルスタックフレームワークで、クライアント 1 種類・チーム一体・集約軽量ならこの選択肢で十分
複数クライアント・集約肥大化・チーム分離・セキュリティ境界のいずれかに該当すれば、技術スタックを問わず独立サービスを検討する
次章: REST 以外の実装選択肢
3 つの選択肢
① BFF 不要
② フルスタックFW
③ 独立サービス
比較と判断
まとめ