Back-end for Front-end Pattern (BFF)

# 入る前に
こんにちは、最近インフラ作業ばかりだが、もっとスペシャルリストになりたいキムと申します。

最近チームで、BFFパターンについて話が出て上がったが、自分はキーワード自体は前から効いてましたが、具体的になんのものなのか、よくわからない状態でした。
今回、すごく理解しやすく説明してくれる外国の記事を発見して、概念を理解することにすごく助かったのでこの場を借りて、共有したいと思います。

## ソフトウェア構成の進化
完全に分産されたアーキテクチャが実行される前には、一般的に一つ以上のレイヤーでアプリケーションを作成してきました。  
階層は高度に結合されましたが、独立したアプリケーション構成要素と言えます。 サービスとは異なり、1つのアプリケーションでのみ使用するようになっている点が結合しているといえます。 同一プロセスの一部として実行されない方式から独立し、しばしば、同一のシステムでさえ実行されないことがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/9fbbb4ee-9719-dcb3-bad9-31287435064e.png)

このようなアーキテクチャはすごく複雑になるかもしれませんが、全般的には他のアプリケーションの間に線をいれて始まりと終わりのポイントがはっきり区分できました。  
各アプリケーションごとデータのレプリカと共通ビジネスプロセスが重複され、時間がすぎるごとにデータを共有したり、ビジネスロジックを再利用できるアプリケーションが必要になっていくことで、最初かなりシンプルだったアーキテクチャは少し複雑になり始めました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/824993f3-c81a-1936-ef1f-605f55d09194.png)

より多くの再利用と、統合が必要になっていくことで、アプリケーションを設計してた集団的な考え方として、サービスと言う少し抽象的な概念にたどり着きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/18d4caf7-8263-44fe-9467-1ad72df72299.png)

上記のアーキテクチャのポイントは再利用可能なサービスが提供する柔軟性です。 結果として、このようなアーキテクチャに基づいたアプリケーションを構築することについては、以下の問題が顕在化しました。

1.必要なサービス選択
2.サービスを呼び出すのにいくつかの接続コードが必要
3. データから得たデータをエンドユーザーになじみのあるデータに併合
4.最終ユーザーが使用できる方式でデータのレンダリング

同時にコンピューターやインターネットはますます人気を集めており、社員やシステム運営者とコミュニケーションをとっていた顧客たちがアプリケーション自体と直接相互作用し始めました。

デザイン思考とユーザー経験に関する研究は、ユーザーをより効率的に作り、ユーザーが理解できるより豊かで有用な環境を作ることに焦点を合わせ、複雑なユーザーインターフェイスから脱するために努力していました。

実はウェブサイトの説明書を読む人はほとんどいないと思います。 ユーザビリティの良い環境を提供するためには、豊富な経験とデータが必要であり、これは様々な出処の情報を収集することを意味します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/41268a77-1ca0-21ac-de82-2c6e4778fd21.png)

LOB（Line-Of-Business）システムのためのユーザーインターフェイスの代わりに、次第に多くのユーザーインターフェイスが独自のアプリケーションに変わっていった。 これらのアプリケーションは、主にJSP、PHP、ASP 等で作成され、このコードは、ユーザインタフェースとアプリケーション別の百円ロジックをすべて含んでいる。

## モノリシック（Monolithic）の終わり
上に述べた簡易な例は、現代の技術組織がアーキテクチャを発展させてきた流れとさほど変わらないと思います。  
2011年SoundCloudのウェブサイトは下記のようでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/b107312e-f83f-c0a4-b73c-94a2dae56e05.png)

すべてビジネスロジックと、処理が一つのシステム内に存在してました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/410dd349-c82c-abbf-16e0-04726e7a53db.png)

SoundCloudの場合Back-endシステムをすごく簡単な形として考えてました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/4a2da59d-98c0-e7d6-9659-55398cbdfdf5.png)

上の考え方は大きい箱を一つのモノリシックで作り出したものになります。実はこの大きい箱な下記のように構成されてます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/2cfe3933-95a9-5b09-83a8-4bb98329ab42.png)

本当は、SoundCloudは一つのシステムをもってるわけではなく、複数のものが存在するプラットフォームをもっており、このアーキテクチャに対する問題点を発見し、マイクロサービスを利用することを決めました。というわけで、下記のようにアーキテクチャを変更することになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/acd36cbf-f65b-63b4-e95c-79e568ae6b2d.png)
バックアンドサービス抽出に成功しましたが、このバックエンドは相変わらずすべてのRequestが集中する重要な経路のままでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/22b4e812-8c58-1ec6-1c6c-af39a18b8718.png)

アーキテクチャ変更の主な動機は新機能のリリース時間を短縮することでした。 そして、この修正によって発生するボトルネック現象が致命的であることがわかりました。
ユーザインタフェースがどれだけ頻繁に変更されるかを考えると、既存のモノリシックコードを抽出することは、生産性を高める直観的な方法でありました。
その上で固有の構成要素からUI 階層を抽出し、共用API からデータを取り込むようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/806195af-2689-2fba-a0de-33538d5198fb.png)

2011年にこのようなアーキテクチャの変化が起きた時、ほとんどのユーザーがウェブを利用しました。 [FredWilson](https://avc.com/2010/09/mobile-first-web-second/)のような人々が予測した通り、結局これは変わり、私たちのユーザーが基盤はWebインタフェースよりもモバイルアプリを使い始めました。
Soud Cloudは、AndroidとiOSのためのモバイルクライアントを提供しました。既存のウェブアプリケーションとPublic APIを利用してモバイルクライアントを支援してきました。

### SoudCloudの課題
自作のAPIを元にしてプロダクトを構築するのは、APIが高い品質を維持して、常に最新状態を確認できる最も良い方法として認識されてます。SoundCloudはこのアプローチ方法に対していくつかの問題点が発見されました。
まずは、プロダクト開発に対する根本的な問題でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/727edcd8-6fa3-77a9-a7af-136f9060d71c.png)

単一プロフィールページを作るためには下記のような複数のAPIを同時に呼び出さなきゃいけいない。
- GET  /tracks/1234.json (作成者）
- GET  /tracks/1234/related.json（関連Track情報）
- GET  /users/7123.json（Trac作成者情報）
- GET  /users/me.json（現在ユーザー情報）
- その他…

上のAPIたちの情報を組み合わせてユーザープロフィールページを作成します。上のアーキテクチャではネットワークボトルネックがあって、新しい機能を追加するたびに、すべてのクライアントが簡単に使えるように時間をかけなきゃ行けなかったです。

## Front-endのためのBack-end (BFFの登場）
上のアーキテクチャを構成してから1年後、SoundCloudは新しいiOSアプリケーションを開発するための準備を進めてました。これは、ユーザー環境を変化させる大規模PJであり、アーキテクチャチームは上の問題たちが、PJに邪魔ものになることを認識しました。アーキテクチャを再び悩まなきゃいけないところでした。

Googleからの最初の提案ソリューションはモバイルやWeb用で異なるAPIを使うことです。 このアイディアはクライアントがAPIを所有しているチームを持っていれば、相互間の調整が必要ではないため、はるかに早く動かせるというものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/03cd2a9f-66f1-97af-8710-7ac48b3a1034.png)
究極にコードを単純化し性能を向上させています。 BFFはアプリケーションのAPIではなくクライアントプログラムの一部だということを発見しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/05c478d7-567e-5221-df34-18f8afb1dc27.png)

## 結論
SoundCloudは、生産性をさらに向上させる方法について研究し始めました。 すべてのアプリケーションに同じユーザプロフィールページが存在したため、すべてのBFFがデータを取得して併合する過程で、多くの重複コードが存在していました。 それでAPIをひとつにしてビジネスロジックを提供するサービスが必要でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/86b7a5b7-4eef-8950-5a88-dcbeb539f993.png)

時間のたつにつれてこの様な状況がどんどん発見されていき、アーキテクチャはこの部分を包容しながら変化していきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/1c5b1c47-d5a6-17f0-e617-e1c2e23da232.png)

# 最後に
いかがでしょうか？  
私はこの記事を読んで、どんな背景で、どのような考え方から、どういった目的をもってからBFFが登場したのかをよく説明してくれたと思います。  
なので、みなさんもご自分のPJにBFFの導入につて考慮するときにどんな目的をもってどのような問題を解決したくてBFFのキーワードが出てきたのかをよく考えてみてください。

原本はこちらです。興味ある方はぜひ読んでみてください。
https://philcalcado.com/2015/09/18/the_back_end_for_front_end_pattern_bff.html