BFF(Backend For Frontend)

何を解決する層か

BFF は、特定のフロントエンドのために用意するバックエンドです。Web版・iOS版・管理画面がそれぞれ別の BFF を持つ、という形になります。

解決するのは次の問題です。

  • 画面が必要とするデータが複数のAPIに散っている — 1画面のために5回 [[REST API]] を叩き、表示が遅い
  • 画面ごとに必要な項目が違う — モバイルは通信量を抑えたいが、Web版は詳細まで欲しい
  • 共通APIが画面の都合で汚れる — ?include=profile,orders,points のような引数が増え続ける

BFF はこれを画面側に寄せて吸収します。1回の呼び出しで、その画面が必要とする形のデータを返します。

[iOS]  → BFF(iOS用)  ┐
[Web]  → BFF(Web用)  ├→ 注文API / 在庫API / 顧客API
[管理] → BFF(管理用)  ┘

APIゲートウェイとの違い

役割が似て見えますが、目的が違います。

[[APIゲートウェイ]]BFF
目的横断的な関心事の一括処理画面固有の都合の吸収
担うもの認証、レート制限、ルーティング、ログデータの集約、整形、画面向けの型
数通常1つクライアントの種類ごと
中身設定が中心業務に近いコードを書く
誰が持つか基盤チームフロントエンドのチーム

両方を置く構成もあります(ゲートウェイの内側に BFF)。ゲートウェイが認証を済ませ、BFF が画面向けの集約を行う分担です。

「BFFにレート制限も入れよう」となったら、それはゲートウェイの仕事です。BFFに横断的関心事を入れ始めると、クライアント数だけ同じ実装が増えます。

GraphQLとの関係

[[GraphQL]] は「クライアントが必要な項目を指定して取得する」仕組みで、BFF が解こうとした問題の一部をサーバー1つで解きます。

BFFGraphQL
誰が形を決めるかBFFの実装者(サーバー側)クライアント(問い合わせ側)
クライアント追加時BFFを1つ足す既存のスキーマから引ける
難しさ数が増えると保守が重い権限制御と負荷制御が難しい

どちらが優れているかではなく、変更の主導権をどちらに置くかの選択です。クライアントが少なく画面要件が安定しているなら BFF、クライアントが多く要求が流動的なら GraphQL が向きます。

導入で気をつけること

  • BFFにビジネスルールを置かない — 判定や計算を BFF に書くと、クライアントごとに挙動がずれます。ルールは下位のサービスに置き、BFF は集約と整形に留めます
  • 障害の連鎖に備える — 5つのAPIを呼ぶ BFF は、1つが遅いだけで全体が遅くなります。タイムアウトと部分的な失敗の扱い(一部が欠けても表示する)を決めます
  • 数が増えたときの共通化 — BFF が3つ4つになると、同じ集約処理が重複します。共通ライブラリへ切り出すか、GraphQL への移行を検討する分岐点です
  • フロントエンドのチームが持つ — 画面の都合を吸収する層なので、画面を作るチームが変更できないと存在意義が薄れます

関連技術とのつながり

  • [[APIゲートウェイ]] — 横断的関心事を担う層。BFFとは目的が異なり併用もできる
  • [[REST API]] — BFFが束ねる下位のインターフェース
  • [[GraphQL]] — 同じ問題を、形を決める主導権をクライアントに渡して解く方式
  • [[マイクロサービス]] — APIが分散していることがBFFを必要にする前提
  • [[SPAとMPA]] — 1画面あたりの呼び出し回数が体感速度に直結する
Q: BFFとAPIゲートウェイの違いとして正しいのはどれ?
- [ ] BFFは認証を担い、ゲートウェイはデータを集約する
- [x] ゲートウェイは横断的な関心事、BFFは画面固有の都合を担う
- [ ] 同じものの別名
解説: ゲートウェイは通常1つ、BFFはクライアントの種類ごとに置きます。併用する構成もあります。

Q: BFFとGraphQLの違いとして正しいのはどれ?
- [x] BFFはサーバー側が形を決め、GraphQLはクライアントが必要な項目を指定する
- [ ] GraphQLはBFFより必ず速い
- [ ] BFFはRESTしか呼べない
解説: 変更の主導権をどちらに置くかの選択です。クライアントが多く要求が流動的ならGraphQLが向きます。

Q: BFFに置くべきでないものはどれ?
- [x] 金額計算などのビジネスルール
- [ ] 複数APIの呼び出しの集約
- [ ] 画面向けのデータ整形
解説: ルールをBFFに書くとクライアントごとに挙動がずれます。ルールは下位のサービスに置きます。