ポリレポ開発で生じていた3つの問題点とは
バクラクシリーズは、「バクラク経費精算」「バクラク請求書受取」「バクラク請求書発行」「バクラクビジネスカード」「バクラク申請」「バクラク電子帳簿保存」の計6つのプロダクトを擁しており、プロダクト間でのなめらかな連携を強みの一つとしている。
バクラクシリーズの前身となる「LayerX インボイス」は、2020年7月から開発に着手し、2021年1月に提供を開始した。BtoB取引マーケットのセンターピンである請求書の受取業務を対象としたものである。
その後、近接領域から徐々にビジネスドメインを拡大していく。2021年4月に「LayerX ワークフロー」を、2021年11月に「LayerX 電子帳簿保存」を提供開始しており、2021年12月にはバクラクブランドへとリニューアル。さらに2022年8月に「バクラクビジネスカード」で決済事業への参入を果たし、2023年8月には「バクラク請求書発行」の提供を開始している。
「バクラクシリーズは、あらゆるデータを連携して、ハタラクをバクラクに変えていくと標榜している。そのため、個々のプロダクトがバラバラに存在しているのではなく、データを共通化して連携させることに重きを置いてきた」と中川氏は強調する。
バクラクのプロダクト開発の変遷をたどってみると、2020年の開発スタート時は、1プロダクトあたり3〜4個のレポジトリで構成されたポリレポ(※1)スタイルでの開発だった。それから2年が経ち、2022年は4プロダクトにまで増え、レポジトリ数が20を超えるようになった。バックエンドはGoに統一されていたが、APIはプロダクトによって異なり、RestやGraphQLが使われていたという。同様に、フロントエンドはTypeScriptで統一されていたが、フレームワークはVue.jsやReactなど、プロダクトによって使われるものは異なっていた。
※1:ポリレポ(Polyrepo)とは、複数のプロジェクトをそれぞれ独立したレポジトリで管理する手法。
この頃は、15〜20人のエンジニアが在籍しており、1プロダクトを2〜3人で開発しているのが一般的。DevOpsやSREの専任者をアサインしない時期もあり、プロダクトに共通する開発基盤チームもなかった。そのため共有ライブラリは一部しかなく、バクラク全体で使える資産はあまりない状態だった。
このようななか、内部通信用のAPIを通じて必要なデータを提供することで、プロダクト間の連携を実現していた。APIをたたいて他プロダクトのデータを参照したり、他プロダクトのデータと結合して検索や出力をしたり、他プロダクトからの非同期通信によるデータの作成や更新をしたりといった具合で、バックエンドシステムに依存関係が生じていた。
特に、大きなドメインを持つサービス同士では、依存関係が循環的につながることにもなりやすい。中川氏はポリレポ開発による循環参照の問題点として、次の3点を挙げた。
- サービス間でのデプロイ順序を定められなくなる。
- 全サービスの中で一貫性のある依存の流れや方向性がなくなる。
- 本来、依存関係のないサービス間にまで、サービスダウンなどの悪影響が波及する。
ポリレポでプロダクトチームが独立して開発を行い、一定の重複するコードを許容することで「他チームに影響を与えずにスピーディーに開発できる」「ライブラリの依存解決などが不要になる」「オーナー不在でメンテナンスされない状態が発生しない」といったメリットもある。ただし、これらのメリットは、上述した循環参照の問題とは別の文脈で考える必要があるという。
ポリレポからモノレポへ
ポリレポ開発で生じていた問題を解消すべく、バクラクでは2022年9月よりモノレポ開発に挑戦することになった。これまでのように1つのレポジトリで1プロダクトを構成するのではなく、より小さなビジネスドメインにフォーカスしたリソースカットでレポジトリを構成することにしたのだ。
「バックエンドは複数のビジネスドメインを区別した形で含める」「フロントエンドはスモールスタートで小さなプロダクトだけを含める」「インフラはデプロイ設定やTerraformなどのIaCも含める」「サブシステムは機械学習系を含めない」という方針でスタートした。
モジュール管理などの言語が持つエコシステムやCI/CDの記述を容易にするため、ルートディレクトリ配下はGo・Terraform・Web(TypeScript)のように言語ごとに分けることにした。また、アーキテクチャ上の各コンポーネントはディレクトリで表現し、その内部に実装を閉じるようにしたうえで、サービスの一覧性を高めるための「サービス」ディレクトリを設け、その下にサービスA・サービスBといった形でマイクロサービスのディレクトリをつくっている。
開発体制に関しては、モノレポ開発になってからも1プロダクトあたり2〜4人という開発体制は変わらないものの、DevOps責任者を常にアサインするとともに、プロダクト開発のパフォーマンス向上を目的とした「Enabling team」を新たに発足させた。
このようなチーム体制になった背景には、『チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計』(マシュー・スケルトン、マニュエル・パイス著、日本能率協会マネジメントセンター)で紹介されている次の4つの基本的なチームタイプの影響があるという。
- Stream-aligned team:ビジネスドメインにおける一連のフロー(機能の開発・リリース・運用)を担当する。
- Enabling team:Stream-aligned teamとコラボレートしながら障害を取り除き、システムや組織に必要な機能の発見や技術の伝搬を担う。
- Complicated Subsystem team:専門知識を要するシステムの開発や運用に携わる。
- Platform team:チームによるデリバリーを加速するための社内サービス(X-as-a-Service)を提供するように振る舞う。
実際にモノレポでの開発体制にしたことで、「相互のチームが同じコードベースから始められる」「Enabling teamはStream-aligned teamとコラボレートする際のコンテキストスイッチが小さくて済むし、仕組みを伝搬するためのコストも小さくて済む」「Platform teamはサービス提供に必要なコストを小さく抑えられる」といったチーム間の相互作用が生まれた、と中川氏は語る。
全プロダクトのフロントエンドのシングルエントリーポイントとして、アーキテクチャには「API Gateway Pattern」を採用。フロントエンドに向けてはGraphQLを公開し、マイクロサービスのAPIは直接公開しないこととした。また、内部通信には「Protocol Buffers」を採用し、ゲートウェイとマイクロサービス間や、マイクロサービス同士の通信で利用している。これにより、モノレポ内で複数個のプロダクトを構成できるようになった。
GraphQLのゲートウェイレイヤーでは、リソースの集約表現やリレーションの解決など、フロントエンドの表示に関わるリソース解決を一手に引き受けている。その代わり、必要なAPIの呼び出しのみを行い、ユーザー入力から出力を生成するオペレーションのロジックには干渉しない。
その裏にあるマイクロサービスのレイヤーでは、ドメインモデリングを行い、APIを設計する。この過程で、顧客と対話するための重要な構成要素や依存関係を明らかにしていく。
こうしてバクラクシリーズのアーキテクチャは、プロダクト同士で依存関係にあったところから、ビジネスのリソースカットによる連携へと進化したのだ。
デメリットを乗り越えてでもモノレポ開発を選ぶワケ
モノレポには多くのメリットがある一方で、ポリレポと比較したときに、2つのデメリットが存在する。
1つめは、コードベースが常に大きくなり続けるという点だ。「コードベース全体をいかにうまく構成し、より短時間でビルドするか」という難題に立ち向かわなければならない。monorepo.toolsでは各々のワークスペースに適したビルドツールの比較情報が提供されているが、現状、バクラクでは特定のツールの導入には至っておらず、「ゆくゆく取り組まなければならない課題として残されている」と中川氏はいう。
もう一つ、注意しておきたいのが、モノレポはデファクトスタンダードではないため、開発者が日常的に使うツールのサポートが十分ではない点である。例えばモノレポでは数が多くなりすぎるために、よく使うGitHubのプルリクエスト一覧やGitHub Actionsのワークフロー一覧の視認性や検索性が落ちてしまうのだ。そのため、バクラクでは現在、デプロイなどはGUIで見るのではなく、独自のCLIコマンドを開発して対応しているという。
これらの課題があったとしても、「モノレポの開発環境下では、ほぼコストゼロでプロジェクトを立ち上げられるし、コードジェネレーターによってデプロイ設定に必要なファイルが自動生成されるため、プロジェクトの立ち上げスピードが圧倒的に速くなった」という。今後もバクラクはモノレポとともにビジネスドメインの拡大を進めていく考えだ。
LayerX Casual Nightへのお誘い
LayerXのプロダクト組織のメンバーと美味しいお酒やご飯を囲みながら、プロダクトやチーム、技術の話をゆる〜く行うイベントを月イチで開催しています。
過去にはクラフトビール会・ご当地ジュース会などを実施しており、毎回満足度の高いイベントとなっています。本記事で興味を持たれた方は、こちらよりぜひお申し込みください!