- 講演資料:新規事業開発を支える技術
基本指針は「事業成長が第一」「事業と技術のバランスを取る」
冒頭で、木田氏は業務で大事にしている2つの基本指針「事業の成長を第一に考えること」「事業と技術のバランスを取ること」について解説。この指針をもとに、さまざまな方針策定を行ってきたという。
「どんなにこだわってシステムを作っても、ユーザーに使ってもらって事業が成長しなければ意味がありません。『いま事業で求められているものは何か』を考えるように、常に心がけています。とはいえ、開発のスピード『だけ』を優先するのもそれはそれで違います。エンジニアとして、『技術的に譲れない部分』は守りたいのです。たとえ新技術にチャレンジしたとしても、品質や開発速度を守れるならば、将来的にはペイできるだろうとも考えています」
そう語った木田氏は、現在取り組んでいるプロジェクトの全体像について解説した。まずは要件定義の話から。彼がプロジェクトに参画した段階では、要件はまだ曖昧だったという。
そこで、プロダクトオーナーとともに要件の洗い出しを行った。プロダクトバックログを作成し、要件をスプレッドシートに書き出していった。その後、書籍『SCRUM BOOT CAMP THE BOOK』を参考に、大まかな見積もりを実施した。
次に行ったのが、開発プロセスの選定だ。新規事業はその特性上、要件の変更が頻繁に起きる。そのため、仕様の変化に柔軟に対応できるスクラム開発を採用した。
その次はアーキテクチャ設計。「開発するシステムはWebアプリケーションのみで、モバイルアプリは開発しない」「運用負荷をなるべく下げたい」といった方針のもと、アーキテクチャの策定を進めていく。試行錯誤の過程で、アーキテクチャの方向性が当初の予定とは大きく変わっていったという。
最初に検討されていたのはSPA+Firebaseによる構成だ。Firebase Authenticationで認証を行い、Cloud FirestoreやCloud Storageの書きこみをトリガーにしてCloud Functionsを走らせるアーキテクチャを想定していた。
「ですが、ピタゴラスイッチ的な設計になりそうなことや、状態をどこに持つべきかが難しいこと、Firebase Authenticationで細かいユーザー管理をしたい場合には自前で実装する必要があることなどがわかってきました。『運用負荷を下げたい』前提があったので、別のアーキテクチャの方が良いと判断しました」
最終的に採用されたのは、Microservices Architecture on Google App Engineだ。Google App Engineはリクエストに応じて自動的にスケールし、デプロイも簡単にできる。また、Function単位ではなくサービス単位でデプロイを行うため、FaaSに比べて複雑な処理にも対応しやすいなどのメリットがある。
各サービス間のやり取りはCloud Tasksによって行い、データベースはCloud Firestoreを用いる方針となった。
フロントエンドとサーバーサイド、それぞれの技術選定の方針
フロントエンドの技術としては、React + ReduxやTypeScript、Next.jsなどが採用された。Reactを使用したのは、Eight開発チームで採用実績があるため知見があること、「個人的にVue.jsよりも好き」といった理由が大きかった。TypeScriptを導入したのは、型定義を用いることによる開発の効率化が目的だ。サーバーサイドにはNode.jsが採用された。
「Node.jsを選んだ理由はいくつかあります。まず、部署内にはRuby on Railsが得意なメンバーが多かったものの、現時点ではGoogle App EngineのStandard EnvironmentでRubyが使えないこと。個人的にRubyの次に得意なのがJavaScriptであること。それから、プロジェクト初期フェーズで少人数チームである間は、メンバーがフロントエンドとサーバーサイドの両方を担当できた方がいいだろうといった判断からです」
Node.jsを選べば、フロントエンドもサーバーサイドもJavaScriptであることから越境がしやすくなる。フレームワークにはExpressを採用。軽量なフレームワークで、マイクロサービスに向いているという。
API設計では、書籍『Webを支える技術』やRuby on Railsのルーティングを参考にして、設計方針の策定を実施。APIドキュメントとしては、デファクトスタンダードとなりつつあるSwaggerを用いた。
「フロントエンドの実装では、StorybookやRedux、Jestなどを用いました。特にStorybookの導入は成功でした。コンポーネント単位で動作確認をしながら開発できるメリットがあるからです。
Reduxでは、Actionsとしてtypescript-fsaを使用しています。もともとはredux-actionsを使おうとしましたが、TypeScriptとの相性が悪かったため断念しました。ReducersとしてはImmutable.jsを使っています。Immutable.jsのRecordという機能を使うことで、Reducerの設計をシンプルにできることが利点です。
また、自動テストのためにJestを用いています。RSpecライクな記法のため、Rubyに慣れた人には馴染みやすく、機能がオールインワンであることも優れています」
さらにサーバーサイドの実装としては、「コントローラーにSwaggerでAPI定義をし、データベースまわりの処理はモデルで行う」「複雑な処理はモジュールに切り出す」「認証やエラーハンドリングなどはミドルウェアで行う」などの基本方針を採用した。
最後に総括として「その事業において、何が求められているかを考えること」「(エンジニアとして)技術的に越えてはいけない一線を守ること」「より良い選択のために、日頃の鍛錬を欠かさないこと」の重要さが改めて語られ、セッションは終了した。
お問い合わせ
Sansan株式会社
- コーポレートサイト
- Sansan Builders Box:Sansanのものづくりを支える技術やデザイン、プロダクトマネジメントの情報を発信しています。