アルプ株式会社の取締役

竹尾正馬氏(以下、竹尾):それでは始めます。アルプ株式会社の竹尾です。本日は「モジュラモノリスで表現する複雑なドメイン領域と境界」について発表します。よろしくお願いします。質問は発表終了後や、Discode内でまとめて回答したいと思います。

まず私、竹尾は、アルプ株式会社で取締役をしています。2018年に会社を共同創業して、エンジニアリング全般を担当しています。新卒の時には、サイバーエージェントのアドテクスタジオという部署でScalaをやっていました。Scala歴は5、6年と長くありませんが、広告基盤のビッティングシステムなどのプロダクトに携わっていました。

大事なのは、ラーメンがめちゃくちゃ好きなことです。好きなラーメンは、ラーメン二郎(八王子)野猿街道店2。ここが今日のハイライトです。Twitterはこのアカウントなので、フォローしてくれたらうれしいです。

アルプという会社について、今回、アーキテクチャの話で組織も関わってくるということで、組織まわりの話をします。現在18人の社員がいて、そのうち10人がエンジニア、6人がバックエンドを担当しています。

サブスクリプションを管理する基盤SaaS「Scalebase」を作っています。「ユーザー自身が何のサブスクリプションを契約をしているかを知るためのサービス」とよく間違えられますが、そうではなく、サービス提供者側の契約管理や決済管理の基盤を提供しています。GitHubの裏側や、Netflixの裏側のオペレーションをSaaS化しているようなイメージをもってもらえればと思います。

創業当初からDDDに全社的に取り組んでいて、Scalaを言語として用いています。クリーンアーキテクチャを採用していて、フロントエンドではReactとTypeScriptを使っています。これ自体は、創業から何も変わっていません。

「Scalebase」を扱うドメイン領域はどういうところか

今日のトピックは「Scalebaseというプロダクトを扱うドメイン領域は、どういうところなのか」というところから話をします。そうすると理解が深まるのかなと思いますし、なぜモジュラモノリスなのかの理由がわかるかと思います。

開発しているScalebaseが直面した課題はなんだったのかの話と、なぜモジュラモノリスにトライするのか。どのようにモジュラモノリスをデザインしたのか。今現在どうワークしているのか。次のステップは何なのかについて、お話しします。

Scalebaseは現在、サブスクリプションビジネスの効率化と、収益最大化を実現するサービスとして運営しています。サブスクリプションビジネスが成長すると、販売商品の複雑化や契約の多様化、請求の管理コストの増大が起きます。そういったオペレーションがボトルネックになり、事業がスケールできなくなるような課題を解決するために、企業のサブスクリプションビジネスの裏側の基盤を、SaaSで提供しています。

もう少し詳しく、どういうところを解決しているかを説明します。複雑な商品設計に対応することが、まず必要です。例えば、サブスクリプションビジネスでは、課金の仕方が従量制や、段階的に変化するような料金プラン。昔でいう携帯の料金プランがわかりやすいと思いますが。商品の複雑さを表現できるサービスでなければならないです。

特にB to Bのお客さまのサービスにおいては、複雑な契約が、お客さま別にカスタマイズされます。その契約単位で、金額や請求方法、請求の頻度、追加しているオプションが違うことがあります。契約の変更が起きることが多く、また、それを歴史としてに追う必要があります。オプションの追加や価格改定、プランの乗り換えなどを実現して、変更の歴史も可視化しないといけません。

契約内容が複雑になれば、当然、請求の管理も複雑化します。Scalebaseを使って契約に基づいた請求金額を計算し、さまざまな決済手段に対応して、ほかのSaaSと接続しながら決済を実現します。例えば請求書払いやクレジットカード払い、銀行振り込みなどがあります。その他にも、サブスクリプションビジネス特有の会計、あるいはSFAの相互接続もやります。

こういう複雑さが足かせになると、お客さまの事業のスケールが難しくなります。「作りたい商品があるけれど、請求のオペレーションが複雑になるからできない」とか。このような状態において、商品・顧客・契約・請求を正しく管理する「Scalebase」というプラットフォームを提供することで、収益の最大化とオペレーションコストの最小化を実現しています。

弊社が扱っているドメイン領域はこんな感じです。顧客、商品、契約、請求が主になります。その他に、外部のSaaSに請求を流し込める請求書を作成する「請求書SaaS」。決済領域と呼んでもいいかもしれません。あとは、請求データや契約データを用いて会計データを作成する領域、取得したデータを元にデータを可視化する分析領域など。

我々のシステムの基盤になる認証・認可もありますし、ここに映っていないものでも、今後どんどんドメイン領域が広がっていくことが考えられます。

創業当初はモノレポでスタート

創業当初は、モノレポでスタートしています。スタートアップの初期は、お金が尽きる前に結果を出さなければいけません。スピードをは本当に大切で、それが命です。そのため、マイクロサービスでスタートすることはほとんど考えられずに、モノレポでスタートすることが自然でした。

アプリケーションも、開発スピードを考えるならRailsも早かったかもしれません。ただ、堅牢性や持続性を考えると「Scalaがいいよね」となりました。前のスライドの「ドメイン領域を扱う」と言ったところは、創業当初から理解していて、最初から「このドメイン領域はあるよね」と、境界を分けようと思えば分けることはできたと思っていました。

2年ぐらいやっていくと、それが間違っていたと気づくこともたくさんあったので、今にして思えば、いろいろな誤りがあったと思います。創業当初は非常にマイクロサービスが流行っていた瞬間でもあり、「やらないと古いと思われないかな」という側面もありましたが。それでもビジネスのフェーズや組織構造からすると、モノレポだけでした。クリーンアーキテクチャを採用し、sbtを使って依存関係を構築し、コンテキスト自体は1つのまま開始しました。

正しいドメインデザインを追求をするための変化

どうして今になってアーキテクチャの進化が求められたかというと、ドメインデザインの改善や進化が目的でした。Scalebaseは一つひとつのドメインが非常に複雑です。それぞれが関連しあって、相互作用し合うビジネスロジックのため、さらに複雑なオペレーションが必要になります。

2年進めていく中で、明らかに異なるコンテキストのドメインが増えてきました。例えば従量制プランの請求計算のために、ユーザーの使用量を必要とします。例として、利用時間などがあげられます。請求コンテキストから見れば、使用量は実績として請求金額の計算に利用されます。一方で、「どれくらい利用したか閲覧したい」という観点から見ると、利用状況がコンテキストになります。

契約自体と使用量などの利用に関する情報は、本質的には違うコンテキストになるかと考ています。請求書という概念も「請求」を同一で扱っていましたが、実は分割することが正しそうだと考えることも我々はあります。それらは、そのアプリケーションの構造上、制約なしの状況化では時間の経過とともに密に結合されていきます。

密になることが、悪いことではありません。ただ問題は、密結合が正しいのかどうかを判断するのが難しくなります。これを制約も何もないモノリシックなアーキテクチャで判別するには、基本的にはレビューしかありませんが、依存が単方向なのか疎結合できているかは構造上浮き出てこないため、認識が困難なレビューとなります。そのため、そもそもレビューで判断すること自体が、難しい現実もあります。

SaaSのような継続的に価値を提供し続けないモデルにおいては、常に正しいドメインデザインを追求しなければなりません。これがドメインモデリング、ドメインデザインで、我々がプロダクト開発するにあたってもっとも大事なことだと考えていて、それをするために「何かチェンジが必要だね」と考えました。

マイクロサービスを採用しなかったわけ

マイクロサービスをなぜ採用しなかったかというと、考慮すべきことが多く、スタートアップには難しすぎるのが率直な理由です。利点としてよく挙げられるのは、デプロイの独立性を保つことで依存が少ない、小さな単位でデプロイし続けられるとか。ドメインのコンテキストがゴチャゴチャにならないように、サービス単位で意識できるとか。

プロダクティビティとスピードの改善の打ち手として、優良なのはあります。ただ考慮しないといけないこともいくつかあり、サービス間通信や分散トランザクション、保証トランザクション。あるいは、サービスのモニタリングやCI/CDの部分でも考えないといけないことが多く、スタートアップのフェーズにとって、これらを考えることは難易度が高い。かなり高い壁として存在している事実があります。

では、我々が受けたい恩恵は何だっけと。「課題は何か」に立ち返ってみます。逆に何が必要ないのかも考えますが、まず第一に、組織のサイズやビジネスのフェーズ的にマッチしないという前提は、マイクロサービスにあります。コンテキストを分けたとしても、デプロイの独立性による恩恵は今のところなさそうだと思っています。

僕たちが現状受けたい恩恵とはそれらではなく、分割してコンテキスト間の依存に制約を持たせることの1点でした。

ところでモジュラモノリスって何?

「ところでモジュラモノリスって何?」という感じなんですが。モジュラモノリスは、マイクロサービスのようなシステムのモジュラリティを改善しながら、テストとデプロイのパイプラインをモノリスのように維持できるアーキテクチャです。モノリスアプリケーションをモジュール単位で分割することで実現します。ShopifyのRailsアプリケーションの中にも取り入れられていて、YouTubeに発表が上がっています。

シングルリポジトリでアプリケーションを構築しますが、中身は2つのコンテキストを維持して分割しています。互いに直接参照できないようになっています。この図でいうと、シングルリポジトリのシングルアプリケーションの中に、ContextAとContextBが存在するかたちです。

我々がモジュラモノリスを選択した理由は、意識的かつ強制的に、コンテキスト分割を実施できるアプリケーションの構築を目的としています。かつ、マイクロサービスに比べると小さく始められ、フレキシブルに方針を変更でき、我々のような小さなチームのトライのサイズとしても適切かと考えました。

このアーキテクチャをどう実現したかをこのあと説明します。アーキテクチャの延長線上にマイクロサービスがあり、モジュラモノリスの1モジュールをマイクロサービス化するときに、移行にかかるコストが少なくて済む点も、後押しするポイントです。

(次回につづく)