楽天グループのEC事業における2つの主軸サービス「楽天市場」「ラクマ」。このAndroidアプリ開発の裏側をご紹介いたします。
楽天グループは「イノベーションを通じて、人々と社会をエンパワーメントする」という想いのもと、「グローバル イノベーション カンパニー」であり続けることを目指し、さまざまなビジネスを展開しています。
この記事では、EC事業の中で2つの主軸サービスである「楽天市場」と「ラクマ」の2つのサービスにおける、Androidアプリ開発の裏側をご紹介いたします。
楽天市場の開発とAndroidアプリ
私たちは“Shopping is Entertainment”をキャッチコピーに掲げるEコマーステックの巨人として、ユーザーにシームレスな体験を提供することを目標としています。
楽天市場Androidアプリは2011年のファーストリリース以降、2021年現在、ダウンロード数1000万以上、高いユーザー評価(Google playストアレーティング4.3)を達成しており、最も人気のあるアプリの中の1つとなっています。
楽天市場Androidアプリの歴史を紐解くと、「変化・変貌」という言葉で表すことができます。
Android OS・開発環境とともに私たちの開発環境も変わりました。
- EclipseからAndroid Studio
- JavaからKotlin + Jetpack
アーキテクチャや使用しているフレームワークも変化し続けました。
- MVC、MVPからMVVM
- ListViewからRecyclerView
- findViewByIdからdata-binding
- AsyncTaskからRx、そしてCoroutineへ
- GoogleAutoFactoryからDagger
また、楽天のグローバルカンパニーへの変貌とともに開発チーム・メンバーも長い期間の中で変遷し、今ではアフリカ、ヨーロッパ、アジア出身の国際色豊かなエンジニアたちが開発に携わっています(バックグラウンドの違いを理解し、お互いを尊重した、和気あいあいとしたチームです)。
開発の課題・難題
楽天市場は日本を代表するEコマースサービスで、その成長を維持するためには定期的に新規機能をリリースし、ユーザーを常に魅了し続ける必要があります。それと同時に品質面では細心の注意、技術面では将来への投資として新しい技術を取り入れていく必要があります。
ただし、この規模のサービス・プロジェクトでは、継続機能開発・品質・技術アップデートを多角的に、バランスを持って維持していくのは簡単に達成できることではありません。あらゆるサービスに言えることですが、1行の変更がもたらすバグでさえもマネタイズに対する問題、法律的な問題など致命的な問題を引き起こす可能性が十分にありえますし、1つの依存の変更が、コンパイルエラーやプロジェクトコード全体に影響をおよぼすことがあります。
また、楽天グループが提供するサービスは数多く存在します。楽天市場はその中でも大規模なユーザーベースを持った核となるサービスで、多くのサービスとの連携がされています。楽天市場内の小さな変更でも、他サービスへの影響は大きく、ビジネス課題・技術課題の解決には詳細で正確な方法が要求されます。
エンジニアチームがとった課題解決の方法論:リファクタリング
私たちは下記の言葉に強く共感しています。
“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” - Martin Fowler
2018年の時点では楽天市場Androidアプリのアーキテクチャは部分的にMVPを採用し、言語はJavaで書かれていました。長年にわたっての継続的な機能開発によって、ソースコードはSOLIDの原則に則っているとは言えない状態でした。これにより、機能開発には時間がかかり、コード変更には常にリスクが伴い、また、品質を保証するためのユニットテストを書くことさえも難しい場合がありました。そこで、Android開発のスタンダードに則るようにソースコードをリファクタリングしようということになりました。
まず第一に考えたことは、開発言語としてKotlinを採用するということです(正直な話、私たちエンジニアはKotlinのシンプルさ、パワフルさに魅了されました。今でもワクワクしながらコードを書いています)。導入に際してはガイドラインを決め、以降、新規機能開発においてはKotlinを使用し始めました。
2つ目の大きな改善としてメインとなるアーキテクチャを変更しようということになりました。アーキテクチャにはその当時から人気があったMVVMの採用を選択しました。書いてしまうと簡単ですが、大規模で複雑な楽天市場というサービスのアプリという点を考慮すると、簡単には決定できませんでした。
まずはアーキテクチャの選定の際に私たちの置かれている環境を考慮しなければなりませんでした。
- 新規機能開発を同時進行で行わなければならない
- 古すぎる既存コードは再利用できない
- ドメインの特性によって1つのアーキテクチャをアプリケーション全体に適応することはできない
- ネットワークおよびキャッシュの実装を刷新する必要がある
そして、新しいアーキテクチャの導入によって達成したいこととして、下記の点を考慮に入れ選定を行いました。
- SOLIDの原則
- ビジネスロジックの検証可能性
- メンテナンス性
- 新規参入者の学習効率
MVVMの他に、MVIやReduxといった各種有名なアーキテクチャを候補として検討し、POCの実施、SWOT分析によって、最終的にMVVMを採用するに至りました。
新アーキテクチャの採用と同時に、新しい技術への置き換え・導入ということも行いました。
- VolleyからRetrofit
- VolleyからGlide
- Timberを使ったlog機能
- DataBinding
楽天市場Androidアプリを使っている方なら思い出していただけるかもしれませんが、2020年にBottom Navigationを使ったUI・UXの刷新が行われました。それは、それらのリファクタリングなしでは実現できなかったことです。それ以降も継続的にサーチ画面のReduxを採用したリファクタリング、Kotlin DSLを使ったネットワークレイヤーの改善を行っています。
変化・変遷の歴史を振り返って
長い道のりを辿って、ここ数年のうちには大胆な決定をし、それを実行してきました。多くの決定は実益をもたらし、そうではない場合にも、そこから得た経験は貴重なものとなっています。
私たちが学んだことは
- アーキテクチャに関する決定は細心の注意を払って行うこと。アーキテクチャの決定は後に長い間、大きな影響をおよぼす
- 新しい技術には盲目的に飛びつくのではなく賢く選択を行うこと
- 二者択一で考えること
- 将来を考えるのに常に過去の経験を参照すること
“What is done cannot be undone, but at least one can keep it from happening again.” - Anne Frank
今後の展望
私たちは過去にやってきたことを継続し、今後も常にMAD(Modern Android Development)に適応していこうと考えています。
Androidの新しい技術の採用としてJetpack Composeの検証も進めています。楽天市場Androidアプリでは、複雑なUI要件に対応するため多数カスタムViewを作成し、使用しています。Jetpack Composeを用いることによって、少ないコード量でさまざまなUI要件に対応でき、それにより品質と開発のスピードを上げることができると考えています。
また、アプリをより疎結合させたモジュール化をすることに取り組んでいます。これにより、さらにダイナミックにスピード感を持って機能の追加・削除が可能になると考えています。大規模なアプリにとってはトラブルシューティングやメンテナンス性などの向上も期待できます。
モジュール化の推進とともに、今までAndroid・iOSプラットフォームごとに構成されていたチームからドメインごとへのチームへと組織を再編成しています。Android・iOSエンジニアの垣根を越えたOneチームとして、楽天市場の成長とエンジニアとしての自己実現を目指し、「変化」していきたいと想います。
ラクマについて
2012年に日本で初のフリマアプリ(当時フリル)として誕生しました。私たちは「Re:Valuation(モノの価値を再定義する)」というミッションを掲げ、日本の消費を変え、人々の生活をより良くすることを目指しています。
サービス統合の苦しみから新体制へ
現在のラクマは、2018年に同じフリマアプリであるFablic社のフリルと旧ラクマの2つのサービス統合を行いました。システムとしてはフリルがベースとなっているため、Androidアプリもフリルをベースに、楽天サービスグループとしてシステム統合や機能追加を行ってきました。
2社のサービスの統合は、事業としては必要な判断でしたが、開発体制としてはやはり大きな傷みを伴いました。
メンバーの離脱や、フリマアプリとしての機能開発よりも、システム統合に開発リソースを割く必要がありました。2018年のサービス統合を行った当時、累計1,500万ダウンロード、年間流通規模1,400億円といった規模でありながら、Androidエンジニアは1名という体制でした。
そのため、もう一度エンジニア組織の再構築から始まり、徐々に新しいメンバーも増え、安定的に新機能をリリースできるようになるまで1年ほどかかりました。現在はiOSエンジニアも含めたモバイルエンジニアチームとしては、全員サービス統合後に参画したメンバーで構成されており、以前のメンバーの想いも引き継ぎながらも、新しい開発組織へと変わっています。
状況の変化に対応しやすい開発環境
ラクマAndroidアプリの開発環境としては、ベーシックな環境を選択してきました。Gitリポジトリ管理にGitHub、CI/CD環境にBitrise、社内アプリ配布にFirebase App Distributionを使用しています。
ユニットテストの自動化や、Slackコマンドを使ってアプリのビルド、デプロイ、Play Consoleへのアップロードなど自動化しています。また、GitHub Actionsなども活用しながらコードレビュー負荷軽減などにも取り組んでいます。
アーキテクチャはMVVM+Clean Architectureを採用しています。
一時はAndroidエンジニアが激減する状況においてもなんとか乗り越えてこれたのは、ベーシックな環境に寄せていたというのもあるかと思います。
Androidネイティブで実装し、クロスプラットフォームなどの技術は使用していません。また、システムとしては一部決済周りなどはWebViewになっており、アプリの領域とWebの領域がある程度はっきりと責務の分離が行えていたため、Android側をシンプルに保つことができたのだと考えます。
オーナーシップを大切に
ラクマのコア・バリューは「Userfirst」「Ownership」「Fail Smart」の3つを掲げていますが、特にAndroidエンジニアとしてはOwnershipを発揮する機会が多いチームとなっています。
私たちは複数の機能開発を同時並行で行いながら、早くプロセスを回すためにCross Functional Teamの体制で行っており、課題に対して、どのように実現していくかはチームで決定していきます。エンジニアでも、デザインやカスタマーサポートについて意見を出したりもします。
職責を超えて意見が出せるカルチャーこそが、より良いサービスにつながっていくと信じています。
現在の課題とこれから
メンバーも増え、チームとしてレガシーなコードからの脱却に挑める体制になってきました。チームでリファクタリングを効率的かつ戦略的に行うために、現在週に1回Androidエンジニアで1時間集まり、リファクタリングの進捗や方向性など共有しています。
大きなトピックとしては、
- JavaからKotlinへのコンバート
- Multi-Moduleの方針検討
- RxからCoroutineへの置き換え
- 新しいJetpackライブラリの導入(Compose、Paging libraryなど)
といった内容です。
レガシーなJavaのコードも残っていますが、Kotlinへのコンバートもチーム一丸となって進めており、2018年時点では70%以上がJavaという状況から、2021年時点ではKotlinが70%を超える状況になってきました。
現在のモジュール構成は、WebAPIへリクエストするネットワーク層のみ本体のモジュールから切り出されている状況です。これから依存関係を整理し、どのように分割していくかを検討している段階です。
さいごに
楽天では、新しい技術にも積極的にチャレンジし、多様なチームでAndroidアプリを開発しています。新しい情報は随時記事として公開していく予定ですので、ぜひブログ等もチェックしていただけたらと思います。
著者紹介
- Yusuf Wagh(楽天市場)
- darquro(ラクマ)