はじめまして!ソウゾウでインターンをしている早稲田大学修士2年のarr0wです!普段は、機械学習の応用系の研究室で悪質なUI/UXを機械学習で自動検出する研究をしたり、アルバイトや個人開発でWeb系の開発をしたりしています。
2月からソウゾウにSoftware EngineerとしてJoinし、3ヶ月ほどメルカリShopsの開発に携わりました。
3月末、インターンを通して実装に取り組んでいた「特集への一括エントリー機能」をリリースしました。本記事では、実装した機能とその技術面に関する説明、インターンを通しての感想について紹介していきたいと思います!
メルカリShopsにおける特集
メルカリShopsでは、「季節のフルーツ・野菜特集」や「訳ありグルメ特集」、「毎月10日は魚の日特集」のようにテーマや食材などを決めて定期的に特集企画を実施しています。
特集に掲載された商品は、「アプリ内の目立つ位置に商品が掲載できる」「SNSやマガジンで紹介される」など様々なメリットが得られます。以下はトップページの画像です。赤枠に囲まれたセクションで、特集に該当する商品が一覧表示されています。
特集の商品は、出店者が管理画面の特集用フォームからエントリーをしています。エントリーされた商品を、メルカリShopsの事務局が人手で一つ一つ確認し、特集の商品として採用するかどうかを判断しています。
従来の特集へのエントリー用フォームでは、同じ特集であっても一商品ずつしか特集へのエントリーができませんでした。そこで、今回のインターンでは複数商品を一括でエントリーできるようにフォームの改良を施しました。
特集一括エントリー機能(成果物)
早速ですが、成果物です。以下が今回実装した特集の一括エントリー機能になります。
特集へのエントリーが完了すると、ショップの出店者に以下のようなメールで通知が送られます。
次の章では、一括エントリー機能を構成する技術要素や設計について見ていきます。
特集一括エントリー機能の実装
メルカリShopsではフロントエンドがNext.js・TypeScript、BFFがNestJSを用いたGraphQLサーバ、バックエンドが、主にGo/gRPCを用いたマイクロサービスで構築されています。現時点で、60以上のサービスがGCPのCloud Run上で稼働中です。この辺りの技術スタックについて、詳しくはメルカリShops立ち上げ時のこちらのブログが大変参考になります。
これらを踏まえて、特集一括エントリー機能について紹介しています。実装の全体を概観するために、シーケンス図を見てみましょう。
一括エントリー用のAPI
特集へのエントリーがフロントエンドから実行されると、topic
サービスのBatchCreateTopicProductApplications
というgRPC APIに、BFF経由でgRPCリクエストが送信されます。
BatchCreateTopicProductApplications
の内部では
- 送信されてきた商品が運営するショップにより販売されたものであるかどうかのバリデーション
- 送信されてきた特集エントリー情報(商品、特集情報)のDBへの保存
- 特集エントリー情報が含まれたPub/SubメッセージのPublish
という処理が実行されます。
既に述べた通り、メルカリShopsのバックエンドは主にGoで実装されていますが、クリーンアーキテクチャ等のアーキテクチャを採用していません。最低限のパッケージ分割はなされていますが、APIの定義された関数・ファイル内で、バリデーションやDBからのデータ取得といったビジネスロジックが実装されています。
一見、可変性やテスタビリティの面で問題がありそうですが、APIに対するE2Eテストで入出力やバリデーション等に対する検証は網羅的に行われています。クリーンアーキテクチャで実装されたAPIサーバと比べ、ファイル数・コード量が少ないため、非常に見通しがよく、個人的にはとても気に入っています。
メール通知の実装
メール通知の箇所では、topic
サービスからPublishされたCloud Pub/Subのイベントを、eventnotification
サービスがsubscribeし、eventnotification
サービス上で処理がなされています。
今回実装した機能のみならず、メルカリShopsではPub/Subを積極的に活用し、マイクロサービスを跨いだ非同期処理が多く実装されています。messageの送信元が送信先に関する情報を知らなくても良いため、疎結合性を保ちながら、マイクロサービス間の通信を実現することが可能です。
特集エントリー用のフォームの実装
メルカリShopsのフロントエンドは既に述べた通り、Apollo Clientを用いて、GraphQL Serverとの通信を行なっています。フォームの実装はreact-hook-formが用いられています。
特集エントリー用のフォームはページ間を跨いで、フォームに入力された値を参照できるようにする必要がありました。そこで、Apollo Clientが提供するReactive variablesにより、グローバルな状態を定義し、各ページから参照しています
ソウゾウでのインターンについて(インターンの感想)
全員ソフトウェアエンジニア
メルカリには全社的に、機能実現や課題解決のために必要であれば、個人の得意分野外の技術領域にも目を向ける「全員ソフトウェアエンジニア」というカルチャーがありますが、ソウゾウはグループの中でもその色が特に濃いと感じています。
個人の意欲(will)次第で、技術領域を横断して機能実装に責任を持つすることができます。実際、私はフロントエンドエンジニアとしてのインターン採用でしたが、バックエンドの実装にも携わりたかったため、特集エントリーの実装では、React / TypeScriptと同じくらい、Goをたくさん書きました。
もともと、個人的にGoを使用して様々なものを作っており、技術スタックのマッチ度合いが高かったので、技術分野を超えて機能開発に自由に参加できる環境は、私にとって非常に合っていると感じました。
業種間の距離が近い
ソウゾウでは、ソフトウェアエンジニア以外のデザイナーやQA、PMなど、異なる専門性を持つ職種の人たちと距離が近いです。仕様やデザイン、QAに関する問題があれば、気軽にSlackで相談できます。
エンジニアがメルカリShopsの改善案を提案することもあるのですが、その際にはSlackに改善案を投稿すると、エンジニア以外のメンバーもすぐに反応してくれるため、エンジニア主導でプロダクト改善案を出す環境が整っています。
実際、私もチームのチャンネルで商品ページに対するOGPの改善案を軽く投げたらみんなが反応してくれ、数日後には提案した改善のDesign Documentを書き始めていたことがありました。スタートアップのようなスピード感はソウゾウならではであり、非常に魅力的だと感じました。(なお、こちらに関しては特集エントリーとは別で実装を進めています。)
終わりに
以上がインターンで取り組んだタスクの紹介と感想になります。
3ヶ月という短い期間でしたが、周囲のサポートのおかげでフロントエンドからバックエンドまで幅広く携われ、今まで勉強してきたWeb系の開発知識を目一杯実務でアウトプットできました。また、単なる機能実装にとどまらず、幅広い経験を積むことができた点も、とても楽しかったです。
Design Documentの執筆やシステム・アプリケーションの設計など、知識面でも勉強になることばかりで、ソウゾウの皆さんには本当に感謝しています。
メルカリShopsでのインターンは、「開発力にある程度の自信があり、学業のみならず、プロダクトの改善にも思いっきり没頭してみたい」という学生には是非ともオススメしたいです。本ブログが、メルカリでのインターンを検討している方の参考になれば幸いです。
メルカリグループでは、インターンを通年、積極募集しています。
「メルカリの開発に関わってみたい!」という方は、ぜひ応募してみてください。