BFF(Backend For Frontend)のメリット/デメリットと導入の是非について
仕事で新規開発PJの開発本格化フェーズに入り、「BFFって実際必要?」みたいな感じの議論になりました。
私はそもそもBFFというもの自体あまりよくわかっていなかったレベルでしたが、実際導入の是非を検討してみたことで、チームの在り方やWebAPIの扱い方次第で答えが変わってきそうな面白いテーマだなあと感じました。
今回自分のチームでは「一旦BFFは無しで行こう」という話になったが、BFFなしで開発進めることでまた新しい発見もありそうな感じなので、半年後くらいに読み返すことができるように、今回どのようなことを考えたのかなど、Scrapにつらつらとまとめていこうと思います。
BFFとは
名前の通り、フロントエンドのためのバックエンド(サーバ)です。フロントエンドのためにAPIをコールしたり、HTMLを生成したりするサーバ
2000年代前半のWebアプリは、HTMLが主体で動きがシンプルだった。しかしWebアプリが技術進化で複雑化するにつれて
フロントエンド側にクライアントごとの要求に応えるためのサーバを配置してバックエンドのAPIサーバとの橋渡し役とするアーキテクチャが開発されるようになりました。
BFFの役割
-
BFFはフロントとバックエンドの姿勢・方針が乖離している場合に仲介役となることができる
- [メリ] バックエンドアプリの仕様が完全に固まっていて変更が難しい場合や、バックエンドとフロントが完全に別チームで開発される場合には「バックエンド側での対応が難しいから、フロント側の開発者がBFFを設け、そこで対応する」ことができる
- [デメ/思ったこと] フロントとバックエンドが気軽にコミュニケーション取れるような環境である/アジャイル開発など、仕様変更に対応しやすい開発手法をとっている ような状況であれば、わざわざBFFを作る必要はないかも
-
バックエンドアプリが持つAPIを、さまざまなデバイス/アプリがクライアントとして呼び出したい場合、APIとフロントのクッション役となる
- [メリ] クライアント側の種類に応じてバックエンドアプリ側のAPIを増やしたり、改修する必要がなくなる
- [メリ] クライアント側のバリエーションを全てBFFが吸収できるので、バックエンドアプリは業務ロジックの表現に集中することができる
- [デメ/思ったこと] アプリケーション自体がシンプルで、フロントアプリとバックエンドアプリが1対1の関係であれば、わざわざBFFを設ける必要はないかもしれない
- [思ったこと] ただ、今後アプリケーションが拡張していってシンプルな状態では無くなった時にはBFFが欲しいとなるかもしれない。その時に初めてBFF導入するのはコスト的にどうなんだろうか?
今回の答え
- 一旦BFFは設けずに、フロントアプリとバックエンドアプリの二本立てで進めることになった。
- フロント側の要望は、バックエンドが用意するWebAPIのIn/Outで吸収する形で対応することにした。
- [理由] 今自分たちのチームはDDDで開発を進めようとしている。ドメイン層を強固で他の層に依存しないものにできれば、プレゼンテーション層はある程度自由がきくと考えている。この考えが正しければ、バックエンドが提供するWebAPIのIn/Outをフロントアプリの要望に合わせて設計しても、バックエンドアプリ自体には差したる影響を与えないと判断できると思ったため。
- [思ったこと] 個人的にはしっくりくる答えだったが、「WebAPIはどうあるべきか」の考え方によっては納得できない答えになるのかもなあと思った
- [思ったこと2] 「WebAPIは個々のクライアントの要望に対応してミニマムに設計されるべき」という考え方なら、BFFなしでの開発(バックエンドアプリのWebAPIがフロントの要望を吸収する)に違和感を覚えなさそうだけど、「WebAPIは本来的にあるべきエンドポイントのみを提供すべき」という考え方なら、フロント側の要望にバックエンドアプリが対応する構造は目論んでいるものとは全く違う構造になってしまうんだろうな
- [思ったこと3] 自分、そもそもWebAPI設計の考え方とかあんまりよくわかってないな。今回導き出された答えについて、バックエンドが専門の人たちはすんなり納得していたけど、フロントエンドが専門の人たちは賛同しつつも何かもやもやしたものを抱えている印象だった。
WebAPIエンドポイントってどう設計すればいいんだろう?
WebAPIのエンドポイントがどのような思想で設計されるべきなのか調べているが、いまいち腑に落ちる状態まで辿り着けていない。
しかし、下記の記事を見ている リソースを中心とした API 設計の整理
みたいな話が出てくる。
リソース URI は動詞 (リソースに対する操作) ではなく、名詞 (リソース) に基づくようにします。
https://learn.microsoft.com/ja-jp/azure/architecture/best-practices/api-design#organize-the-api-design-around-resources
上記のような説明を見ていると「フロント側がこういうデータを一気に返すようなAPIを求めてるから、そういうエンドポイントを追加しよう」みたいな考え方は違うんだろうなあという印象。
(後でしっかり目を通したい記事たち)
(続き)
ところで、ここでいうリソースは =ビジネスエンティティ
だと考えてしまっていいんだろうか?
全然頭の中がまとまってないけど、フロントとバックエンドで同じモデルを共有し、画面のコンポーネントがモデルのエンティティ単位で表現できるようなデザインにできていればあんまり悩むことはないんだろうなあ
そういう意味だと、 フロントエンドとバックエンドの間でドメインに対する考え方や開発手法が乖離しているのであれば、バックエンドのAPIエンドポイントがフロントの要望を拾い上げることはデメリットが多くなるので、やはりBFFを作った方が良い
という選択になるんだろうなあと思った(1週して戻ってきた気がする)
一旦の答え
- 組織的にDDDを取り入れている私たちのチームとしては、下記のことが言えるのではと思った。
- DDDで要件定義・画面デザインを進めているのであれば、ドメインモデルから大きく乖離するような仕様のAPIをフロントが求めるような事態にはならないはず
- もしそのような事態になるのであれば、チームの活動とアウトプットに課題があると言えそう(ドメインモデルが業務を正確に表現できてないとか、画面デザインがやりたいことがドメインモデルと乖離してるとか)
開発ペース的に、年末には仮説に対する答えが出ていそう。