メルカリ ハロ アプリの技術スタックの紹介

こんにちは。メルカリ ハロでSoftware Engineerをしている @atsumoです。連載『Mercari Hallo, World! -メルカリ ハロ 開発の裏側-』の第5回を担当します。

メルカリ ハロではメルカリアプリ内にある「はたらくタブ」とは別にクルー向けのアプリ(ストアで「メルカリ ハロ」と検索してみてください)を用意しています。本記事では、アプリ版のメルカリ ハロで使用している技術とその選定理由、さらにリリースまでの開発の進め方などを踏まえてご紹介したいと思います。

この記事で得られること

  • メルカリ ハロのアプリの技術スタック
  • その技術選定の理由と効果
  • 開発の進め方とヒント

技術スタック

メルカリ ハロ アプリで使っている技術スタックをいくつかピックアップして紹介できればと思います。

フレームワーク: Flutter

第2回の記事の中のメルカリ ハロのモバイルアプリの技術選定でも記載がありましたが、メルカリ ハロは マルチプラットフォームフレームワークのFlutterを採用しています。導入決定までの決断などは第2回で触れられているのでそちらをご覧いただければと思います。そちらの記事の中でも妥当な決断であったとありましたが、リリース後にアプリ開発に関わっているメンバーで振り返りを行った際も、開発効率の向上とサービスとしての品質の担保の両方行うことができ、良い選択だったという意見が多かったです。

開発人数が少ない中、両プラットフォームを同じタイミングでリリースすることができたのはFlutterを採用したことがとても大きかったです。

CLI: Melos

Melosは複数パッケージをもつDartプロジェクトの管理に使用されるCLIツールです。
メルカリ ハロではモノレポ(monorepo)を採用しており、下記のような言語ごとのディレクトリ構造になってます。

├── dart
│   ├── analysis_options.yaml
│   ├── apps
│   │   ├── widgetbook
│   │   └── hallo_app (ハロ アプリ)
│   ├── melos.yaml
│   ├── packages
│   │   ├── hallo_design_system (デザインシステム)
│   │   ├── hallo_linter
│   │   └── ...
│   ├── pubspec.lock
│   └── pubspec.yaml
├── go
...
└── typescript

開発当初、Flutterのプロジェクト自体は1つで複数のパッケージはなかったのですが、後でデザインシステムや社内のシステムを使うものはパッケージに分けていく構想があったため、開発開始時点からMelosを導入していました。初期は主にコマンドをまとめるための用途としてしか使っていなかったのですが、リリース後少し落ち着いたタイミングでデザインシステムをパッケージ分割したり、社内のサービスを使うためのパッケージが増えていったりと複数パッケージを持つプロジェクトとなり、引き続き力を発揮してくれています。

通信: GraphQL

モバイルアプリとバックエンドの通信にはGraphQLを採用しています。

メルカリ ハロのアプリでは GraphQLを使用するための packageとして graphql_flutter, graphql_codegen を使用しています。

バックエンド側で定義した graphqlのschemaとアプリ側でアクセスするgraphqlファイルを元に graphql_codegen でGraphQLのサーバーにアクセスするためのファイルを自動生成しています。

サーバリクエストとレスポンスデータのキャッシュはgraphql_flutterが行ってくれるため、次にお話しする状態管理において構成を単純化するのに大きく寄与しました。

状態管理について

公式ドキュメント Differentiate between ephemeral state and app state に ephemeral state(一時的な状態管理) と app state(それ以外の状態管理) と分かれて記載されているのでそれに沿って説明します。

Ephemeral state (一時的な状態管理)

Widget内やScreen内で完結するようなステートには flutter_hooks を使用しています。具体的には StateWidgetでのStateにもたせていたようなものには useStateを使用しています。画面を開いた際に画面の閲覧のログなどを送信したい場合には useEffectなどを使用しています。さらに必要に応じてカスタムHooksを作成しています。

App state (サーバリクエストとレスポンスデータ / グローバルステート)

サーバサイドリクエストやキャッシュ

GraphQLでのやり取りをするために、graphql_flutterを使用しています。graphql_flutterはApollo Clientをモデルとしたgraphqlのpackageです。

Apollo Clientはローカルとリモートデータの両方をGraphQLで管理することができる包括的な状態管理のライブラリです。ただ現在、Apollo ClientはFlutter版のpackageがないため、その代わりとして Apollo Clientをモデルとして作られている grahql_flutter を選択しました。

GraphQL自体の仕組みや graphql_flutter が持つキャッシュの仕組みによって、クライアント側で独自の管理をする必要をなくし、状態管理の複雑性を削減しています。
※ graphql_codegenが生成する hooksのメソッドを使用しています

グローバルステート

画面を構成するうえで必要な情報はgraphql_flutterの情報から取得するのですが、複数画面に使用されるものや認証情報などに関しては Riverpodを使用してグローバルステートとして管理しています。

デザインシステム

デザインシステム_button

メルカリ ハロのアプリでは、メルカリのデザインシステムではなく、独自のデザインシステムを採用しています。ここでお話するデザインシステムは主にデザイントークンやUIコンポーネント、そのデザインデータや実装されたコンポーネントなどを指しています。 基本的にコンポーネントをベースに画面のUIデザインが行われています。立ち上げ時にはひたすらUIコンポーネントを実装してWidgetbook(後述)で確認し、一通りコンポーネントを実装し終わったあとに画面の実装に入っていきました。

Figma上のComponent propertiesでBooleanやTextだけでなくInstance SwapやVariantを用いてデザインしてもらっていたので、実装する際も他のWidgetがプロパティとして入ることが想像でき、デザインデータとして変更できるプロパティと実装上コンポーネントのプロパティのギャップが少ない状態を作ることができました。

各画面のデザインは主にコンポーネントを使った構成になってます。実装時にはコンポーネントを配置し、プロパティの値にFigmaのものを入れていくというシンプルな作業になり、生産性が非常に高く保たれたと感じています。

画面が増え、機能が増えることで、当時は想定できていなかった見せ方が必要になり、コンポーネント自体のアップデートであったり、新たなコンポーネントを追加することもありますが、初期の段階からある程度コンポーネントができていて画面実装に入れたのはとてもありがたかったです。このようにコンポーネントを先行して実装していく進め方は、他のプロジェクトでも参考にしていただけるのではないでしょうか。

開発したコンポーネントは、次に触れるWidgetbookを使用してカタログとして閲覧できるようにしています。

UIカタログ: Widgetbook

widgetbook

Widgetbookはフロントエンドでよく使われるStorybookのFlutter版のようなツールで、デザインシステムで定義したUIコンポーネントや実装したWidgetなどをカタログのように表示することができます。

デザインシステムとして用意しているUIコンポーネントをカタログのように見れることで、途中からチームに参画したメンバーもUIコンポーネントとして用意してあるものを一覧で見ることができたので、画面実装する際もスムーズに行うことができたという声もありました。

画面実装が進むにつれて実際の画面で確認することなどが増えましが、特定条件でのみしか表示されないようなUIに関してはWidgetbookを使用して素早く確認することができとても重宝しております。

現在Widgetbook 3を使用していますが、Widgetbook 4ではGoldenテストを再利用することができる仕組みやモノレポ(monorepo)での使い勝手などを考慮した改善などが検討されているようなので、次のバージョンを期待しています。

まとめ

メルカリ ハロのアプリ開発では、いくつかの技術選定が開発を進める上で大きな役割を果たしてくれました。

  • Flutterの採用により、少人数でのスタートにも関わらず、iOSとAndroidの両プラットフォームを同時にリリースすることができた。
  • 将来的なパッケージの分割も見据えて、モノレポ(monorepo)でのプロジェクト管理にMelosを導入したことで、複数パッケージの管理が容易になった。
  • バックエンドとの通信にはGraphQLを採用することでサーバーとのやり取りがスムーズになり、状態管理の構成をシンプルに保つことができた。
  • 開発当初からデザインシステムの構築を最優先に進めたことで、デザイナーとの共通言語ができ、Widgetbookを使ってカタログ化することで開発効率を大幅に向上させることができた。

私たち開発チームにとって、これらの技術選定と開発方針が、メルカリ ハロのアプリ開発を支える大きな力になったと感じています。

さいごに

メルカリ ハロアプリの開発では、FlutterやGraphQLなどをはじめとする多様な技術を採用しましたが、あくまで現在のチーム状況やサービス内容において適した選択でした。まだまだサービス的にもシステム的にも改良の余地があるので、常により良いものを探求していきたいと思っています。

プロジェクトごとにフィットする技術や方法は異なると思いますが、今回ご紹介したメルカリ ハロでの事例が、みなさんにとって最適解を見つけるためのヒントになれば幸いです。

Links

連載:Mercari Hallo, world! -メルカリ ハロ 開発の裏側-

メルカリではメンバーを大募集中です。メルカリ ハロの開発やメルカリに興味を持った方がいればぜひご応募お待ちしています。詳しくは以下のページをご覧ください。

  • X
  • Facebook
  • linkedin
  • このエントリーをはてなブックマークに追加