BFF(Backend for Frontend)を自分の言葉で腹落ちさせたメモ

BFF(Backend for Frontend)を、なんとなく「良いものらしい」で済ませてたんだけど、ちゃんと自分の言葉で説明できるか怪しかったので腹落ちさせた。best friend forever じゃない。

書いてて気づいたんだけど、自分には「困りごとを表示の都合で語りたくなるクセ」がある。BFFの話も最初「画面サイズが違うから必要なんでしょ」と思ってた。これが落とし穴だったので、その軌道修正も込みでメモにしておく。


汎用API1本だと、誰かが必ず損する#

出発点はここ。汎用APIを1本だけ用意して、Webもスマホも全部それで賄おうとすると無理が出る。

レストランで例えるとわかりやすかった。メニュー1種類だけで、誰が来ても全部乗せの特大プレートしか出さない店。がっつり食べたいWebの広い画面ならまだいいけど、電車でスマホ見てる人には食べきれない料理が山ほど運ばれてくる。

つまり汎用API1本は全員に同じ形しか返せないから、誰かが必ず損する。逃げ道は2つしかなくて、どっちもつらい。

  • あれもこれも詰め込む → スマホが表示すらしないデータまでダウンロードさせられて遅い(オーバーフェッチ)
  • 最小限に絞る → 足りないぶんを何度も取りに来させて往復が増えて遅い(アンダーフェッチ)

ここが大事で、この損は画面サイズが違うから生まれるんじゃない。さっきの自分のクセが出るところ。本当の軸は次のセクションで効いてくる。


解決はクライアント種別ごとの専用バックエンド#

そこで、フロントと下流サービス群のに、クライアント専用のバックエンドを挟む。これがBFF。

置き場所はバックエンド側(サーバーサイド)。フロントの中じゃない。ここを勘違いしがちなので自分用に強調しておく。

仕事は2方向で1セットなのがポイントだった。

  • ほしいデータが3つのサービスにバラバラに散ってるとき、まとめて叩いて統合する
  • そこからそのクライアントに要るぶんだけ選択する

集めて、削る。片方だけだと不完全で、両方やって初めてBFFの仕事になる。おまけにフロントは本来3サービスに3回投げるところを、BFFに1回投げれば済むから往復も減る。

自分の言葉で定義を1文にするとこうなった。

BFFとは、クライアント種別ごとに1つずつ置かれ、フロントとバックエンドの間で、下流のデータを選択・統合してクライアント専用の形で返すバックエンド。

「画面ごと」じゃなく「クライアント種別ごと」#

立てるのは Web用に1個、iOS用に1個、Android用に1個、とクライアント種別ごと。商品一覧画面に1個、カート画面に1個、みたいに画面ごとには立てない。

理由は前のセクションの損に戻る。オーバー/アンダーフェッチの差は画面が違うから生まれるんじゃなくて、クライアントが違うから生まれる。回線・ペイロード耐性・認証の作法、そのへんが種別ごとに違う。だから別バックエンドを立てる切れ目も、画面じゃなくクライアント種別に引く。同じWebなら一覧画面もカート画面も同じ制約を共有してるから、1個のWeb-BFFで足りる。

認証も同じ理屈で説明できた。作法がクライアントごとに違う(Webはcookie/セッション、モバイルはトークン)から、すでにクライアントごとに分かれてるBFFに置くと収まりがいい。

要するにクライアント種別ごとに差が出るものは、すでに種別ごとに分かれてるBFFに集めると収まる。フェッチ最適化も認証も、この一本の原理の具体例にすぎない。ここが見えると一気にスッキリした。


持つのは誰か、そして代償#

最初「BFFはFEエンジニアが書くもの」と思ってたけど、これも違った。

BFFはそのフロント専用だから、フロントの都合が変われば一緒に変える。このときそのフロント体験を持つチーム自身がBFFを握ってると、別チームに「項目足して」と依頼して順番待ち、という渋滞が起きない。自分たちで握ってれば独立して進化させられる(疎結合・自律)。

肝心なのは、そのコードを実際にタイプするのがFEエンジニアかBEエンジニアかは、この旨みに関係ないってこと。旨みを生むのは「どのチームが握ってるか」であって職種じゃない。だからBFFは技術の話というより組織の所有権の話だった。

で、旨みを生んだ「種別ごとに専用BFF」という同じ構造が、そのまま代償も生む。

  • 3つのBFFが似たコードを各自で持つ(同じ下流を叩く処理・認証・エラーハンドリング)→ コード重複
  • 運用対象がN個に増える(デプロイ・監視・脆弱性パッチが3倍)

天秤にかけるとこうなる。

内容
払うものコード重複N倍 + 運用N倍
買うものクライアントごとの最適化 + チームの自律

ここから言えるのは、クライアントがWeb1種類だけで下流もシンプルなら、種別ごとの差を最適化する旨みが出ない。旨みが出ないのに重複と運用だけ払うのは割に合わない。だからBFFは万能の善じゃなくて、クライアント種別が複数あって初めて元が取れる、条件付きの道具だと思っておくのがちょうどいい。種別が増える・下流が散らばる・チームが分かれてるほど効いてくる。

で、誰がメンテすんの?#

正直な引っかかりも残しておく。もし実プロジェクトで導入を提案されたら、一番不安なのは「で、誰がメンテすんの?」ってところ。

BFFは「フロント体験を持つチームが所有する」と言うけど、所有する=そのチームがGo/Nodeのサービスをデプロイ・監視・パッチし続ける責任を負う、しかも種別ごとにN個。「自律できて嬉しい」の裏は「N個のバックエンドの面倒を自分たちで見る覚悟」でもある。フロントチームにバックエンド運用の体力が無いと、所有はご褒美じゃなく重荷になる。ここは導入前に正面から見ておきたい。


ひとことイメージ#

最後に一言でまとめると、BFFは API Gateway をクライアント種別ごとに専用化した特殊形。ただし「種別が複数あるとき限定」の、という但し書き付きで覚えておく。

BFF(Backend for Frontend)を自分の言葉で腹落ちさせたメモ
https://p4ni.com/posts/what-is-bff/
作者
kpab
公開日
ライセンス
CC BY-NC-SA 4.0