フロントエンドアーキテクチャ

BFF設計 ― Backend For Frontendを薄く保つ ― 生成AI時代のアーキテクチャ超入門

BFF設計 ― Backend For Frontendを薄く保つ ― 生成AI時代のアーキテクチャ超入門

本記事について

当サイトを閲覧いただきありがとうございます。 本記事はシリーズ『生成AI時代のアーキテクチャ超入門』の「フロントエンドアーキテクチャ」カテゴリ第6弾として、BFF(Backend For Frontend)について解説する記事です。

「共通APIで誰も幸せにならない」問題への解答として 2011 年に SoundCloud が提唱した設計パターン。本記事ではBFFの背景・典型責務・実装パターン(Next.js API Routes/tRPC/Hono)・BFF vs GraphQL・アンチパターン・AI時代の型共有まで解説し、「薄く保つ・必要になってから導入する」という運用の鉄則を示します。

このカテゴリの他の記事

「共通API」で誰も幸せにならない

flowchart LR
    WEB[Web<br/>大画面・SEO要] --> BFF_W[Web BFF<br/>OG画像/SEO/フル情報]
    MOBILE[Mobile<br/>狭帯域] --> BFF_M[Mobile BFF<br/>軽量・必要最小限]
    TV[TV App<br/>独自UI] --> BFF_T[TV BFF<br/>大型画像/縦リスト]
    BFF_W --> MS{Microservices}
    BFF_M --> MS
    BFF_T --> MS
    MS --> SVC1[Auth]
    MS --> SVC2[Catalog]
    MS --> SVC3[Cart]
    MS --> SVC4[User]
    classDef client fill:#fef3c7,stroke:#d97706;
    classDef bff fill:#dbeafe,stroke:#2563eb,stroke-width:2px;
    classDef ms fill:#fae8ff,stroke:#a21caf;
    class WEB,MOBILE,TV client;
    class BFF_W,BFF_M,BFF_T bff;
    class MS,SVC1,SVC2,SVC3,SVC4 ms;

従来は「1つの汎用API」を全クライアントで共有するのが普通でしたが、Web・モバイル・TVではそれぞれ画面サイズ・必要データ・認証要件が全く違うため、共通APIでは誰も幸せにならない、という問題がありました。BFFはこの問題を「クライアントごとに最適なAPIを提供する中間層」で解決します。

クライアント毎に責任を分離するのがBFFの思想です。

BFFが生まれた背景

BFFパターンは、2015年頃に SoundCloud のエンジニアが提唱し、その後 Netflix・Spotify・Twitter などのモバイルアプリで採用されて広まりました。マイクロサービス化が進んだ結果」、フロントエンドが数十の異なるAPIを叩く必要が出てきたことが背景にあります。

従来: 1つの汎用APIを全クライアントで共有
[Web] ──┐
[Mobile]─→ [単一API] ──→ [Backend]
[TV]  ──┘

この構造の問題は、「Web用の変更がMobile側に影響する」「各クライアントが使わないフィールドまで取得している」「クライアント毎の認証要件が混在する」という3点です。Webとモバイルでは通信料の制約も違うため、1API共有は現実的ではない、と認識されるようになりBFFが生まれました。

BFFの典型的な責務

BFF「フロントの下請けをする薄いサーバ」が理想です。業務ロジックはバックエンドサービスに残し、BFFは表示・整形・プロキシに徹するのが健全な設計です。

責務内容
APIアグリゲーション複数のマイクロサービスから集めて1画面分にまとめる
データ整形画面に合わせた形式に変換・不要フィールド削除
認証・セッショントークン管理・Cookie化・秘密鍵の隠蔽
キャッシュAPIレスポンスのHTTPキャッシュ・エッジキャッシュ
レート制限DDoS対策・API悪用防止

特にAPIアグリゲーションが重要で、画面1つを表示するために「ユーザー情報・注文履歴・レコメンド・広告」を別々に叩く必要がある場合、BFFが裏で「並列呼び出し」して1レスポンスに束ねられます。ブラウザが5回リクエストする必要がなくなり、体感速度が劇的に改善します。

BFFの典型構成

最も一般的な構成は、Next.jsなどのフルスタックFWを BFF層として使うパターンです。フロントと同じリポジトリに置くことで、UI開発とAPI整形を「同じチームで扱え」ます。

[Browser]
   ↓ (same-origin通信・Cookie)
[Next.js API Routes / Server Actions]  ← BFF層
   ↓ (mTLS / 内部ネットワーク)
[Microservices / 外部API]

BFFの所有者はフロントエンドチームで、フロントと同じリポジトリに置くのが鉄板です。画面の変更に合わせてBFFも変わるため、リポジトリが分かれていると変更コストが跳ね上がります。同居していれば「画面を変えたらBFFも同時にPR」という流れで完結します。

なぜBFFが有効か

BFFを挟むことで得られる具体的な効果は、大きく3つに整理できます。これらは単純にAPIを直接叩く構成では得られないものです。

① セキュリティの向上

ブラウザから直接外部APIを叩くと、APIキーや認証トークンがブラウザ側に露出します。BFF経由にすれば、トークンはサーバ側にだけ保持でき、ブラウザにはhttpOnly Cookieだけを渡せます。XSS(Cross-Site Scripting、スクリプト注入攻撃)でトークンが盗まれるリスクを根本的に排除できます。

② パフォーマンスの向上

複数のマイクロサービスを呼ぶ処理をBFF側で並列化」し、1つのレスポンスにまとめて返せます。ブラウザ↔BFF は同一オリジンで高速、BFF↔バックエンドは内部ネットワークで高速、という「二重の最適化」が効きます。

③ フロントエンド開発効率

フロントチームがAPIの形を「自分で決められる」ため、画面に必要なデータだけを綺麗に整形できます。バックエンドチームに「このフィールド追加して」と依頼する往復がなくなります。

BFFの実装パターン

BFFの実装手段は多岐にわたります。フレームワーク組込み型が簡単で、tRPCのような型安全型が尖った選択肢として人気です。

パターン備考
Next.js API Routes / Server ActionsReact系で最も普及
Nuxt Server RoutesVue系で同等の選択肢
Remix Loader/ActionWeb標準重視の設計思想
tRPCTypeScript型共有で神業級の開発体験
Hono + Cloudflare WorkersエッジBFF・低遅延
専用 Express/Fastify軽量・FEと独立リポジトリ

Next.js Server Components と Server Actions の登場により、BFFを別に作る」必要が減り、BFFはフレームワーク組込が主流になりつつあります。シンプルな用途なら Next.js だけで完結できます。

tRPCによる型安全BFF

tRPC は、TypeScriptの型をサーバとクライアントで完全共有する仕組みで、近年急速に普及しました。RESTGraphQL のようなスキーマ定義なしで、関数呼び出しのようにAPIを書けます。

// サーバ側
const appRouter = router({
  user: {
    byId: procedure.input(z.string()).query(({ input }) => ...)
  }
})

// クライアント側 — サーバの型が自動で効く
const user = await trpc.user.byId.query("u_1")
// user の型は自動推論・入力はZodでバリデーション

利点:スキーマファイル不要・型でエディタ補完・実行時バリデーション(Zod(TypeScript用スキーマ定義ライブラリ)との統合)。TypeScriptフルスタック(同一プロジェクト内にFE/BEが同居)の場合、圧倒的な開発効率を発揮します。

Next.js + tRPC + Zod が現代の型安全フルスタック最強構成です。

BFF vs GraphQL

BFFと似た問題を解く技術としてGraphQLもあり、どちらを選ぶかは迷いがちです。両者は「排他的ではなく」、組み合わせることもできますが、得意分野が異なるため使い分けが重要です。

観点BFFGraphQL
実装画面毎にエンドポイント単一エンドポイント
学習コスト軽い重い(設計・運用が難しい)
柔軟性サーバ側で固定形に整形クライアントが自由にクエリ
キャッシュHTTP標準で簡単別途設計が必要

BFFが合うケース」:クライアントがWeb/モバイルなど少数で、画面設計が安定している場合。GraphQLが合うケース」:多様なクライアント(モバイル・TV・外部パートナー)が自由にクエリしたい場合。

単一クライアント中心ならBFF、多様なクライアントが自由にクエリしたい時はGraphQL が定石です。

セッション管理の定石

BFFを使う場合の認証は、「ブラウザにはCookieだけ、BFFの裏で実トークンを管理」という定石があります。この構成が、XSS耐性とトークン管理の両方を最大化します。

1. ブラウザ → IdP(Identity Provider、認証基盤、Auth0等)でIDトークン取得
2. BFF に IDトークン送信
3. BFF が検証し、httpOnly Session Cookie 発行
4. 以降のAPI呼び出しは Cookie ベース(ブラウザ側は JWT を一切触らない)
5. BFF が裏で Access Token / Refresh Token を管理

この構成の決定的な利点は、ブラウザにJWTを一切露出させないこと。XSSでSession Cookieが盗まれる可能性はhttpOnly化で排除でき、万が一盗まれてもサーバ側で即時失効できます。JWTをブラウザに持たせる設計と比較して、セキュリティが一段上のレベルに到達します。

BFF + httpOnly Cookie が現代のWeb認証の最も安全な構成です。

BFFのアンチパターン

BFFは便利な反面、適切に薄く保たないと急速に肥大化して、新たな負債になります。典型的な失敗パターンを押さえておかないと、BFFそのものがもう一つのモノリスになります。

  • 肥大化:業務ロジックがBFFに流れ込み、中核サービスと二重化する。修正時に両方変える羽目に
  • サイロ化:各BFFが独自にユーザー管理やキャッシュを始め、一貫性が失われる
  • キャッシュの置き場所問題BFF内・バックエンド内・CDNのどこで何秒キャッシュするかが混乱する
  • 認証の多重化:各BFFが独立に認証実装を持ち、認証バグが各所で発生する

BFFフロント用の薄い層。業務ロジックを持ち込むと中核サービスと二重化して破綻します。

「BFFが本体になった日」(業界事例)

「バックエンドチームの対応が遅いから」という理由で、Next.js API Routes 側に割引計算や在庫引当のロジックを書き溜めた結果、1年後にはBFFが実質的な本体・本物のBackendはCRUDの置き場、という逆転構造になった現場の話が、いろいろな勉強会で共有されています。修正時は両方を直す必要があり、結局二重メンテで疲弊する顛末です。

「Next.jsでサクッと書いちゃおう」という発想が半年後に恐ろしい規模の逆転を生んでいた、という光景はいろいろな現場で目撃されています。この事故の怖いところは、個々のPRレベルでは”ちょっと書くだけ”で済んでいたこと。1行の割引計算が、1ヶ月後には在庫引当に、半年後にはポイント計算に、1年後には「中核ロジックの大半」になっていた、というのが典型パターンです。

BFF「入口では無害に見えるが、放置すると必ず肥大化」する。「玄関ロビーに金庫を置くな」という教訓は、こうした事故の積み重ねから生まれています。

BFF薄く保つが鉄則。業務ロジックが入り込む兆候を早期に叩きます。

BFF導入の段階別判定表

BFFは入れる・入れないの判断が最も重要で、規模と構成から自動的に決まります。以下が実務での段階表です。

フェーズ規模・構成BFFの扱い実装方式
個人・MVP〜1,000 MAU不要(直接API叩き)fetch + useState
初期スタートアップ〜10,000 MAU・単一バックエンド薄いBFF(FW組込)Next.js API Routes / Server Actions
中規模SaaS10,000〜100,000 MAU・複数マイクロサービス統合BFFtRPC + Next.js
大規模100,000 MAU〜・多チーム専用BFF層(画面ごと)専用Express/Fastify + gRPC
マルチクライアントWeb + Mobile + TVクライアントごとBFF各クライアント専用
エッジ配信優先グローバル・低遅延重視Edge BFFHono + Cloudflare Workers

BFFを入れる実質下限はマイクロサービス化 + 3サービス以上の集約が必要」の時です。それ未満では Next.js API Routes / Server Actions の薄い層で十分で、専用BFFサーバを立てるのは過剰設計です。

BFF必要になってから「将来のために」で先取りすると運用コストで逆戻りします。

BFF設計の鬼門・禁じ手

BFF運用で事故る典型を整理します。どれもBFFが本体化する肥大化の入口になります。

禁じ手なぜダメか
BFFに業務ロジックを書く1年で中核サービスと二重化。玄関ロビーに金庫を置くな
BFFをバックエンドチームが所有画面変更のたびに他チーム調整。フロントチーム所有が鉄則
BFFとFEを別リポジトリに分離画面変更で2つのPRが必要、同期タイミングで事故
BFFにキャッシュ戦略なしオリジンへの負荷が集中、BFFがボトルネックに
BFFで認証を再実装(各BFFが独立)認証バグが各所で発生。統一認証に寄せる
REST + 手書き型でBFFとFEを繋ぐ型が分断、型定義の二重管理。tRPCで完全共有
BFFのタイムアウト未設定バックエンド障害でBFFごと倒れる雪崩連鎖
BFFで楽観ロックなしの更新同時更新でロストアップデート、データ破損
BFFをフロント以外のクライアントからも叩かせるBFFの意味が消える。用途特化を保つ
マイクロフロントエンドでBFFを1つに統合チーム独立性が失われる。各フロントにBFF

「2024年時点の定番はNext.js Server Actions + tRPCServer Componentsで取得、Server Actionsで更新、tRPCで型共有。この3点セットでBFFという別層」を意識せず実装できます。伝統的な別サーバBFFは、マイクロサービスが5本以上・多チーム並列開発になる時だけ検討します。

BFF玄関ロビー。業務ロジックを持ち込んだ瞬間に二つ目のモノリスになります。

AI時代の視点

AI駆動開発が前提になると、BFF「型共有によるAIの理解促進」に価値が集中します。tRPCやNext.js Server Actionsのようにフロントとバックエンドで型が共有される構成は、AIが「この関数はこの型を返す」と正確に把握できるため、生成コードのバグが激減します。逆にRESTの独自スキーマで型が分断されていると、AIは推測で書いてハルシネーションを起こします。

AI時代に有利AI時代に不利
tRPC(型完全共有)手書きREST + 型定義の二重管理
Next.js Server Actions(ファイル内で完結)別リポジトリのBFF・分散した仕様
Zodスキーマでバリデーションstring検証の手書き
同一リポジトリでFE/BE同居リポジトリ分離・仕様が遠い

AIが扱うコードの範囲は「一度に見えるコンテキスト」で決まるため、FE/BFF/BEが同一リポジトリで同じ型を共有する構成はAIにとって最も理解しやすい状態です。tRPC + Next.js + Zod のスタックは、AI時代に再評価されている構成です。

よくある勘違い

  • BFFに業務ロジックを書いてもいい → 書き始めた瞬間から肥大化が始まり、1年で本体化する。BFFは薄く保つが鉄則
  • 小規模でもBFFを入れた方がモダン → 個人開発や中規模SaaSには過剰設計。Next.js API Routes / Server Actionsで十分
  • BFFGraphQLは同じ → 解く問題は似ているが哲学が逆。クライアント少数ならBFF、多クライアント自由クエリならGraphQL
  • ブラウザにJWTを持たせればシンプルXSSで一撃。BFF + httpOnly Cookieが現代の安全構成

決めるべきこと — あなたのプロジェクトでの答えは?

以下の項目について、あなたのプロジェクトの答えを1〜2文で言語化してみてください。曖昧なまま着手すると、必ず後から「なぜそう決めたんだっけ」が問われます。

  • BFFを設けるか(規模と構成から判断)
  • 実装技術(Next.js / tRPC / Hono / 専用サーバ)
  • リポジトリ構成(FEと同居 / 別リポジトリ)
  • 認証の扱い(Cookie / Bearer / Session)
  • キャッシュ戦略BFF内 / CDN / どちら優先か)
  • ロギング・監視(相関ID・OpenTelemetry

最終的な判断の仕方

BFFの核心は「薄く保つこと」と「導入判断を規模から逆算すること」です。BFFは画面に最適化された整形・集約・認証プロキシに徹する層であって、業務ロジックを抱え込ませると中核サービスと二重化して破綻します。

個人開発や中規模SaaSに独立BFFサーバは過剰設計で、Next.js API Routes や Server Actions でフレームワーク組込の薄いBFF層を作るだけで十分です。本格的なBFFが必要になるのは、マイクロサービス化 + 多様なクライアント(Web/Mobile/TV)が揃った時」だけで、その時も「フロントチーム所有・フロントと同一リポジトリ」という原則を守らないと変更コストが跳ね上がります。

決定的な軸は「型共有 + 同一リポジトリ」です。tRPC + Next.js + Zod はフロント・バック・AIの3者で型を共有する最強構成で、AIが「この関数はこの型を返す」と正確に把握できるためハルシネーションが激減します。REST + 独自スキーマで型が分断されると、AIは推測で書くしかなく、フロントとバックで仕様がズレる事故も起きやすくなります。

さらにBFF + httpOnly Cookie」の認証構成は、ブラウザにJWTを一切露出させずXSS耐性を最大化できるため、現代Web認証の事実上の標準になっています。BFFは「技術パターンである以上に組織の責任分担を技術に落とし込む仕組み」で、フロントチームの所有権を尊重する運用が成功の鍵です。

選定の優先順位をまとめると次の通りです。

  1. 規模から必要性を判断(小規模は不要、マイクロサービスで必須)
  2. フレームワーク組込を優先(Next.js API Routes / Server Actions)
  3. 型共有 + 同一リポジトリtRPC + Zodが最強)
  4. BFFは薄く保つ(業務ロジックは中核サービスに残す)

まとめ

本記事はBFFについて、責務・実装パターン・GraphQLとの違い・アンチパターン・型共有まで含めて解説しました。如何だったでしょうか。

BFFは薄く保ち、規模から必要性を判断し、型共有+同一リポジトリでAI生産性を最大化する。これが2026年のBFF設計の現実解です。

次回は認証認可(フロント側)(Cookie/JWT保管・XSS/CSRF対策)について解説します。

シリーズ目次に戻る → 『生成AI時代のアーキテクチャ超入門』の歩き方

それでは次の記事も閲覧いただけると幸いです。