『マイクロフロントエンド』

先日こんな本を買いました。

www.oreilly.co.jp

オライリーから出版された「マイクロフロントエンド」という本です。

今日はこちらの本について書いていきたいと思います。

マイクロフロントエンドとは

マイクロフロントエンドという言葉自体、耳馴染みが無い方も多いと思います。僕もそうです。

マイクロフロントエンドとは、自律的、独立してデプロイ可能、かつ単一のチームが所有するビジネスドメインのことです。

Luca Mezzalira 著、嶋田 健志 訳 『マイクロフロントエンド』p.27

まだちょっと抽象的です。具体的に見ていきます。

通常、新しくプロジェクトを立ち上げプロダクト開発を進めていく際にはそのビジネスが成功するかどうかの検証からスタートします。

コストを抑え、必要最低限の機能に絞り、最小限のプロダクト(MVP: Minimun Viable Product)を作り、ユーザーからの情報を集めます。

その際、多くの場合はモノリシックなアプリケーションとして設計されます。

サービスがスケールするにつれてモノリスからマイクロサービスへと移行していく、というのがよく見られるケースです。

ドメインごとに独立したAPIやDBを持ち、各チームは担当のドメインに対して責任を負います。

しかしAPIやDBはデザインパターンやベストプラクティスがあればスケールできるのに対し、フロントエンドについてはどうでしょうか?

昔からフロントエンドをスケールさせる選択肢はあまり存在しませんでした。

というのも、ビジネスロジックを持つファットサーバと処理結果を表示するシンクライアントが標準的であったため、その必要性が無かったからです。

しかし、ユーザーの行動の変化に伴ってUXの水準が向上し、質の高いコンテンツやサービスを維持しながらユーザーの希望を実現するためのスムーズな道筋を提供する必要性が高まってきた。

言い換えればサービスにおけるフロントエンドの重要性が高まってきたということです。

そうした背景から新機能の追加を迅速に、かつアプリケーションの一部を単体でリリースできる手法が必要となりました。

これがマイクロフロントエンドです。

ここまでの説明を振り返るとマイクロサービスそのものといった感じですが、著者はマイクロサービスの原則はマイクロフロントエンドにも適用できるとしています。

  • ビジネスドメインのモデル化
  • 自動化の文化
  • 実装の詳細を隠す
  • ガバナンスの分散
  • 独立デプロイ可能性
  • 障害の分離
  • 高い観測性

また巻末に収録されているマイクロフロントエンドを実践している開発者へのインタビューではこんな一文もありました。

――マイクロフロントエンドを3語で表現すると?

Microservices for frontends. (フロントエンドの/ための/マイクロサービス)

Luca Mezzalira 著、嶋田 健志 訳 『マイクロフロントエンド』p.346

というわけでマイクロサービスアーキテクチャをフロントエンドで実践するには、というのが本書のテーマです。

ただ、すべてのプロダクトをマイクロフロントエンドにすべきというわけではありません。

デメリットがメリットを上回る場合は採用しないよう著者も呼びかけています。

マイクロフロントエンドは、その性質上、また技術的・組織的なレベルで複雑さを増す可能性があるため、すべてのアプリケーションに適しているわけではありません。

Luca Mezzalira 著、嶋田 健志 訳 『マイクロフロントエンド』p.24

マイクロフロントエンドの実践

意思決定フレームワーク

まずはどのようなアーキテクチャにするか、その意思決定のフレームワークを見ていきます。

水平分割 / 垂直分割

  • 水平分割

水平分割は複数のビューにまたがるパーツごとにフロントエンドを分割する方法です。

つまり1つのビューの中に複数のマイクロフロントエンドが含まれることになります。

柔軟性の高い手法ですが、何百ものマイクロフロントエンドが存在することにならないよう規律やガバナンスが必要となります。

  • 垂直分割

垂直分割は各チームが1つのビジネスロジックに関わるフロントエンドを担当する方法です。

これはドメイン駆動開発に近い考え方と言えます。

マイクロフロントエンドにおいてもコンテキストの境界を定義づけるにはビジネスの仕組みをよく理解することが必要であると書かれています。

構成

マイクロフロントエンドの構成は大きく分けると3種類あります。

  • クライアントサイドコンポジション
    • CDNまたはオリジンサーバからロードしてクライアントでビューを構成する
  • エッジサイドコンポジション
    • オリジンサーバからロードしてCDNレベルでビューを構成する
  • サーバサイドコンポジション
    • オリジンサーバレベルでビューを構成し、CDNにキャッシュさせる

ルーティング

通常は構成と同じレベルでルーティングを行うことが多いです。

マイクロフロントエンド同士でのコミュニケーション

マイクロフロントエンドは単体で完結しているため、通常は相互にやり取りする必要はありません。

しかし、水平分割の場合等同じビューに複数のマイクロフロントエンドが存在している場合はビュー全体として整合性が取れている必要があります。

その為、フロントエンド同士のイベント通知の方法についても考慮する必要があります。例えば以下のような手法です。

  • イベントバスを通じてすべてのマイクロフロントエンドに通知する
  • カスタムイベントを使う
  • Webストレージ / cookieを使う
  • クエリパラメータを使う

これらの観点を元にチーム内で選定し、実装を進めていきます。

ただし、すべてを満たす完璧なアーキテクチャは存在しないと著者は述べています。

本書の他の箇所でも指摘したように、私は完璧なアーキテクチャは存在せず、常にトレードオフの関係にあると固く信じています。トレードオフは技術的なものだけでなく、ビジネス要件や組織構造にも基づいています。現代のアーキテクチャは、技術的な側面だけでなく、最終的な結果に影響する他の力を考慮します。「完璧なアーキテクチャ」を探したり(これは存在しない)、他のコンテキストからアーキテクチャを借りてきて、それが我々のコンテキストに適切かどうかを調査する代わりに、社会技術的側面を認識し、我々が活動するコンテキストに対して最適化しなければなりません。

Luca Mezzalira 著、嶋田 健志 訳 『マイクロフロントエンド』p.53

つまり、アーキテクチャの選定よりも前に自分たちが活動するコンテキスト、チームの構造、チーム間のコミュニケーションフローを時間をかけて理解することが大切であるということです。

他の企業やチームで上手くいった事例をそのまま取り上げるだけでは全くフィットしない可能性もあります。

自分たちのチームの特性や事例にあった他社の特性との違い、背景、解決しようとしている課題等、総合的に判断する必要があります。

自動化

マイクロフロントエンドには自動化は不可欠です。

先程このように書きました。

新機能の追加を迅速に、かつアプリケーションの一部を単体でリリースできる手法

CI/CDといった自動化パイプラインが整備されていなければこれらの実現が難しくなります。

パイプラインが整備されていればリリース時の負担は少なく済みますし、また何かトラブルがあっても速やかに対応できます。自動テストによってバグを未然に防ぐこともできます。

マイクロフロントエンドを取り入れる理由の一つに小さな単位で迅速に改善を重ねることが挙げられると思うのでCI/CDを始めとした自動化は常に整備しておく必要があります。

また、フロントエンド全体に対してCIを行うよりもビルド時間やテストの実行時間なども短くなるというメリットもあります。

フィードバックループを高速に保ち、最適化する手法を理解する必要があります。

テスト戦略

自動化に関連してテスト戦略も考慮が必要です。

例えば垂直分割のマイクロフロントエンドのE2Eテストを行う場合、担当するドメインのテストだけでなく異なるドメインとの接点となるテストも作成する必要があります。

また水平分割の場合はどのチームがどのテストを作成するのか、チーム間での調整が必要となります。

デプロイ戦略

最後に継続的デプロイ(CD)戦略についてです。

マイクロフロントエンドは単体で独立してデプロイできることが前提です。

コードベース全体や他のマイクロフロントエンドに影響を及ぼすことなく、アプリケーションの一部のみをリリースできます。

単体でリリースできるということはアプリケーション全体を破損させるリスクやユーザー体験を損なう可能性を回避することもできます。

つまり、すべてのユーザーに対して新しいバージョンをリリースするのではなく、ブルーグリーンデプロイやカナリアリリースを採用することでトラフィックの一部に対してのみリリースし、本番環境でのテストに合格した後に切り替える、ということです。

マイクロサービスで有効な手段はマイクロフロントエンドでも同様に採用することができます。

まとめ

以上、簡単ではありますが「マイクロフロントエンド」の内容をまとめてみました。

本記事では割愛しましたが、事例やインタビューも豊富に載っていて内容の濃い1冊でしたので気になった方はぜひ。

取り入れるのは結構難しそう、というのが率直な感想です。

垂直分割だとドメイン単位で開発できるというメリットはありますが、ドメイン間での統一感であったり重複したコンポーネントも沢山出てきそうだなと。

逆に水平分割だとUI上の統一感はクリアできても大元のアプリケーションの管理はどうするのかや、後テストが結構大変そうだなと思いました。

いずれにしても著者も書いている通り、チームや組織について理解すること、議論することがかなり重要であると改めて感じました。

フロントエンドの設計についてはまだまだ知識も実践も不足しているので引き続き勉強していきたいと思います。