超簡易なBFF(Backend for Frontend)を作ってみた
BFFがどんなものか知るため手を動かして作ってみました。業務で使うから作ったというより業務に使えるのか考えるために作りました。
※改善部分があればぜひコメントをください
BFFについて
この記事がいろんなところで参照されてます。お時間があれば一読してみてください
Pattern: Backends For Frontends
BFFとは
BFFはBackend For Frontの略です。
複数プラットフォーム(Web版とモバイル版)で異なるUIを構成するためのデータ取得を行ったりマイクロサービスで動いてる複数WebAPIを集約しフロントエンドへデータを渡すAPI Gatewayのような使われ方をする
1.異なるUIを構成するためのデータ取得の図
2.マイクロサービスで動いてる複数WebAPIを集約しフロントエンドへデータを渡すの図
企業での導入
1.合同会社EXNOA様
DMM GAMESのプラットフォームリプレイスを支えるBackends For Frontends (BFF) の裏側
2.ZOZO様
Backends For Frontends(BFF)はじめました
BFFを作ってみる
全体構成
今回の構成だとBFFはただの中継者でしかない。
今回はBFFというレイヤーを作ってみたかっただけなので今後ロジックを積んだBFFも試していく予定です
Backend
言語/ライブラリ
Backendのコードを小さく保ち、大きくなりすぎたらサービスを分けるマイクロサービスに向いてるたgoを採用。
また、sqlcでクエリを自動生成するようにしてます。sqlcを採用したのはDB操作の処理を自動で作ってもらい楽をするためです
sqlc
Frontend
言語/ライブラリ
よく書いてて一番慣れているためReact.jsをTypeScriptで採用
BFF
言語/ライブラリ
Express(TypeScript)を採用
「BFFはフロントエンドが書く」という記述が見られたためフロントの人でも学習コストが少なく挑戦ハードルが低いものを選びました
NestJSやApolloも考えましたが、最小構成で作ることを考えた際にオーバースペックだと感じましたため今回は不採用しました。「GraphQAやDIを使いたい!」ということがあれば検討したい
動作確認
- goを起動
- Node.jsを起動
- React.jsを起動
- localhost:3000へアクセス
- authorsの一覧が表示される
コード
コードはGitHubにあります
BFFに触れて感じたこと
コードを小さくできるので複雑なことを考えなくて良くなりそう
小さくサービスを分けて分けたそれぞれのサービスをBFFでまとめるという戦略が取れるので大きなコードを小さい複数のものに分けることができる。影響範囲が小さくなるので「こちらを改修するとあちらに影響が...」みたいなことがなくなりそうです。
技術選定の幅を広げられそう
モノリシックでなくても良くなるので「この機能はあの言語で実装しよう」と各機能ごとに言語を変えることができる。"人工知能の処理が関わる部分はPythonで書き、並行処理が求められる部分はgoやElixirで書く"なんてことができる
もちろん利用言語が増えれば全体としての認知負荷は上がります。メリットでもありデメリットにもなります。
小さいサービスに適応するのは旨みがなさそう
「そもそもWebでの提供しか考えていない」だったり「モノリシックでも複雑性がなくまだ機能も少ない」というサービスには向いてないと考えている。
複雑性を無理やり持ち込んでしまい運用コストに対する効果が得られないと自分は考えています。
まだニーズがあるかわからないサービスを開発する時は最初からBFFを採用せず、モノリシックや単純にフロントとサーバーに分けた簡単な構成でサービス開発するのが良さそう。サービスが成熟しリアーキテクトを行うときの選択肢としてBFFはアリ
まだわからない部分が多い
後述するが、1.認証認可 2.マイクロサービスによる可用性の向上 3.マイクロサービス間のトランザクション管理 etc...が自分にはまだわからない。
集約サーバーとしてのBFFをどうやって実サービスに組み込んでいくのかの知識が自分にはまだ足りない。今回のデモを元により本番導入を意識したBFF構成を知っていく必要がある
今後に試したいこと
BackendやFrontendの追加
今回作ったデモは正直BFFを導入するメリットがない。Backendを増やしてBFFの集約を試す。
また、Frontendも1つしかないのでFrontendを増やしてみる
テストコードを書いてみる
今回のデモにテストコードはない。
本番導入するならテストコードが書けることが必須だと思うのでテストコードの書き方や自動テストで何をみるのか基準を知る必要がある
サービスの可用性を考える
各マイクロサービスのデータを集約する最終、ある1つのマイクロサービスとの通信が失敗したらどうするのだろうか?
サービス全体を止めずに失敗した部分だけ切り離してフロントへデータを渡すべきなのか?また、その実装をどうするのか?
マイクロサービスでのDBトランザクション
モノリシックだとトランザクションの貼り方が容易です
しかし、マイクロサービスだとトランザクションってどうやって管理するのだろうか?2相コミットとか?
まとめ
実務で全く使わないがよく聞くBFFに触れてみた。今まで考えて来なかったことを考えたり調べたりするのは楽しい。
理解度を深めるには実際に手を動かしたり何か自分でサービスを作ってみるのが良さそうなので今回作ったデモを成長させながらBFFへの理解を深めていく
Discussion