DroidKaigi 2019 登壇報告 "Server-side Kotlin for Frontend: 複雑なAndroidアプリ開発に対するアプローチ"

表題のタイトルで登壇してきましたので、この記事で紹介および補足をしたいと思います。資料は以下です。

また、セッションの動画もアップロードしていただいています。50分ですが、結構早口でしゃべっているので、特に内容に興味があって全てを吸収したいという方がもしいらっしゃれば、動画を見ていただくのが効率が良いかもしれません。

ちなみに、参加者としての記事も書いたのでよければそちらもよろしくお願いします。

関連する資料など

今回引き合いに出した、過去の登壇資料などのリンクです。

マイクロサービス指向 Rails API 開発ガイド (ぎんざRuby会議01, qsona)
カイカクジャーニー ~ スタートアップが必ずぶつかる課題と開発チームのメジャーバージョンアップ (Rails Developers Meetup 2018 Day 4, takayukishmz)

また、BFFを含めた「マイクロサービスとフロントエンド」というテーマでは、不定期で開催している Microservices Meetup でも多く議論してきています。登壇の資料やパネルディスカッションの内容などまとめてありますので、興味を持ってくれた方はぜひあわせてご覧ください。

Microservices Meetup Vol.5 (API Gateway & BFF) を開催しました
Micro Frontendsの未来が見えた議論。 Microservices Meetup Vol.7 開催レポート
クライアントサイドとマイクロサービスの難しい関係 — Microservices Meetup Vol.9 (FiNC App & Frontend) 登壇内容レポート #microserv

登壇内容の補足

ありがたいことに、セッション終了後に質問を多くいただきましたので、改めて返答したく思います。また、資料の最後から2ページ目にフリートーク用のスライド1枚があるのですが、それについても補足します。

Q. 神APIがBFFに作られてしまうことにならないのか?

これに対しての自分の答えは"No"です。

神APIというのは、いろんな用途に使える万能なAPIで、パフォーマンスの悪化を引き起こします。 GET /me とか GET /mypage とかでよくあるやつです。トークの中では、Backendに存在する神APIを解体して、集約をBFFに寄せるという話をしました。

BFFのAPIは基本的に単一目的で、特定の Use Case のようなものに紐づいて存在するべきと考えます。目的が1つであれば万能に作る必要はないので、神にはなり得ないと思います。

・・・というような返答をした覚えがあるのですが、本当に1つのAPIが1つの目的でしか使われないのか、はちょっと悩んでいる部分があります。

Q. モバイルエンジニアが開発するということだが、従来バックエンドサービスで行っている負荷対策などはどうするのか?

BFFも、バックエンドと同等(以上)の負荷対策/監視/etc...が必要です。ですので、そういった面はサーバー/インフラエンジニアとの協力が基本的に必要になると思います。

なお、BFFの負荷を考える上では、「バックエンドサーバーの応答が遅くなりリクエストが詰まる」というパターンを強く想定しておく必要があります。Non-Blocking I/O を利用すると解決する部分もありますが、コネクションプールが枯渇するなどの問題もあるので、タイムアウトを適切に設定するとかになります。すでにService Meshが構築されていてその中に入れるならあまり気にしなくていいかも。この辺はBFF特有ではなくマイクロサービス一般の話なので、社内で詳しい人に相談するとよさそうです。

Q. 全てのリクエストはBFFを通すのか?

これは最初Yesだと思ったんですが、悩ましいところです。

まず、更新系は基本的にBFFの集約の出番はありません。

また、BFFにおけるAPI合成が必要ない場合もあります。単にバックエンドのリソースをそのまま取得して使えるなら、わざわざBFFでラップする必要もあまりないかもしれません。

そのような場合にほしいのはBFFというよりは、ただのProxy的なものです。(ProxyがあるとリクエストするURLドメインが1つになったり、認証を任せられるので、本来は嬉しい。) これをAPI Gateway と呼ぶことにします。

すると、考えられるのは、 (1) BFFの中にProxy的な機能を拡張するか、もしくは (2) 別途 API Gateway を置いて、BFFは本当に必要な一部のリクエストだけを通すようにするか。FiNCでもちょうど二年前くらいに議論していたときは (2) のパターンが挙げられていました。

まあちょっとこの辺は、その組織に現状あるものに引きずられる部分もあるのかもしれません。すでに API Gateway があるなら、うまく活用しつつBFFとの役割の棲み分けをするのがよさそうですが、一般的にどういうパターンが良いかの明言はいまのところできません。

未来のアーキテクチャの話について

最後から2枚目のスライドは、キーワードだけ羅列しておいて、そのまま7分くらいしゃべりました。動画を見ていただいてもよいのですが、その内容をちょっと整形して公開します。

まず、マイクロサービスは何のためにあるかというと、「Agility を高める」、つまり、例えばデプロイを独立してできることにより、ユーザーへの価値提供のサイクルを高速化するためです。これが最大の目的です。

しかし、クライアントサイドはどうでしょうか。モバイルアプリはしばしば巨大なモノリスになりがちです。しかも、アプリにはリリース申請があるので、サーバーのように好きなタイミングでリリースできるわけではありません。結果として、マイクロサービスの恩恵を受けられていません。つまり、本来はアプリまで考えて価値提供の高速化を考えなければならないのに、実際にはマイクロサービスはサーバーの独りよがりになりがち。僕は個人的に、この状況に一石を投じたいと思っています。

マイクロサービスの理想形は、APIだけでなく、UIまでをアジャイルに変更できることです。Webフロントエンドの世界には、Micro Frontendsという考え方があります。これは、BFFとはちょっと対極にあるような考え方で、各マイクロサービスがAPIだけでなく、Web Componentsという、頭を持ったUIコンポーネントまでを返します。フロントエンドはAPIを合成してUIを作るのではなく、そのUIコンポーネントを配置して、その間のイベントのやりとりだけを司ります。(詳細はぜひこちらを。 Micro Frontends の理論と実践 -価値提供を高速化する真のマイクロサービスのあり方 )

では、Android/iOSアプリはどうか? Webとちがってサーバーはアプリのコンポーネントを返せないので、同じことはできません。ではどうするか?

まずはモジュール分割。(今回のDroidKaigiではModularizeの話が多くありましたね!) モジュール分割の単位を、できるだけマイクロサービスと合わせる。すると、たとえばPRのマージを速めることができます。モジュール内のコードの変更が他のモジュールへの影響はないと判断できるなら、そのコードを所有するチームだけがレビューしてマージ出来るからです。結局、デプロイはアプリ全体で足並みを揃える必要はあるのですが、少なくとも master ブランチにマージできる速さがあがるので、間接的にはAgilityを高められていると思います。

つぎに、アプリ自体を分割することです。デプロイを分離できて、真のAgilityを獲得できるからです。正直、FiNCアプリでいうと、10個くらいにアプリを分割できると思います。ただ、これが出来るかはビジネスマターでもあります。よほど多くのユーザーに支持されているアプリならともかく、そうでなければ、10個もアプリをユーザーがインストールしてくれるのか?などという、AndroidとかiOSのプラットフォーム上の問題が出てきます。マイクロサービスの分割とはわけが違うのです。(もしかしたら、Instant Appsのような技術が解決してくれる可能性もあります。)

さらに、UI層はバックエンドほどきれいに分割しにくいという問題もありますね。

そういったアプリのモジュール分割やアプリ自体の分割といった戦略も含めて、みんなでマイクロサービスの真の目的を達成できるといいと思っています。

一方で、今のような話が仮に進んだとしても、BFFの役割がなくなるわけではありません。今日紹介した「ためる・つかう」機能のように、Backendに存在しないドメインをFrontendが作り出しているケースでは、依然として、BFFが使い続けられると思います。

そういったクライアントをひっくるめたマイクロサービス戦略のことを、弊社のAndroidエンジニアの南里さんが"Micro App"と名付けていたので、今年はMicro Appをホットな技術課題に挙げていきたいと思っています。興味がある方、これからも一緒に議論していってくれたら嬉しいです。

おわりに

補足は以上になります。セッションについて不明な点や、このテーマについて議論したいことなどがあれば、ぜひ qsona (twitter) にメンションください。(もしくはこの記事にコメントを付けていただいても反応できると思います。)

補足だけでずいぶん長くなってしまったので、登壇までの過程などのエモ記事は別にわけます。

noteの通貨流通量を増やしていきたい!!