Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TypeScriptとモジュラーモノリスで挑む複雑なWebアプリケーション開発

 TypeScriptとモジュラーモノリスで挑む複雑なWebアプリケーション開発

Katsuma Narisawa

July 25, 2023
Tweet

More Decks by Katsuma Narisawa

Other Decks in Programming

Transcript

  1. TypeScriptと

    モジュラーモノリスで挑む

    複雑なWebアプリケーション開発
    2023年7月25日 モジュラモノリス徹底解剖〜実践者から学ぶLunch LT〜
    成澤 克麻
    SALESCORE株式会社 CTO

    View full-size slide

  2. Katsuma Narisawa
    東北大学で自然言語処理

    → 株式会社ディー・エヌ・エー

    → 株式会社ラブグラフ

    → フリーランス

    → SALESCORE株式会社のCTO


    直近はTypeScript, GraphQL, Prisma,

    Recoil, Turborepoあたりが好き

    趣味:食、酒、旅、写真、漫画

    View full-size slide

  3. 最近noteがバズりました

    2300+スキ!1100+はてブ!感謝!

    View full-size slide

  4. 見覚えのある単価…

    View full-size slide

  5. Why

    Monolith?
    Modular

    View full-size slide

  6. Why

    Monolith?
    Modular A. 複雑なサービスを

    作り上げるため

    View full-size slide

  7. 一つのことを行い

    またそれをうまくやるプログラムを書け

    協調して動くプログラムを書け

    View full-size slide

  8. 複雑なサービスを、1つ1つのシンプルな

    「モジュール」を組み合わせて作り上げる
    なんか色々なロジック…
    色んなことをやるモノリス モジュラーモノリス
    INFRA
    AUTH
    INFRA2
    COMMON
    DOMAIN2
    APP
    DOMAIN1
    PRESENTATION1 PRESENTATION2

    View full-size slide

  9. 会社紹介 & 開発体制
    社名:SALESCORE株式会社

    事業内容:営業ドメインでSaaSとコンサル


    創業メンバーの出身企業

    キーエンス、DeNA


    現在の開発メンバーの出身企業

    DeNA、PFN、LINE、Tesla、PLAID、Yahoo


    4年ほど一人開発

    今年からPdM、デザイナー、エンジニアx3が増えました(詳細はAppendix)

    View full-size slide

  10. 営業組織向けSaaSを謳いつつ、中身は

    任意のデータを、任意の形で可視化・編集できるサービス

    セールスイネーブルメントの実現には

    様々なレイヤーの大小様々な支援が必要

    → つまり、非常に複雑…!!


    ※営業ドメイン、意外と面白いよ!PRレビューみたいなのがあったり。

     ぜひnote読んでください。
    「ドメイン特化型Full-Stack Data Platform」


    「推測するな、計測せよ」


    サービス紹介

    View full-size slide

  11. どれだけ複雑か? - 一般的なデータパイプライン
    Data Source
    ELT TRANSFORM DWH
    BI
    REVERSE-ETL
    User
    SALESFORCE

    View full-size slide

  12. どれだけ複雑か? - SALESCOREのデータパイプライン
    Data Source
    ELT TRANSFORM DWH
    BI
    SHEET
    REVERSE-ETL
    User
    SALESFORCE
    →普通は複数サービスでやることを単一サービスで実現

    View full-size slide

  13. どれだけ複雑か? - ダッシュボード機能
    ユーザー設定のKPI(集計条件)を

    ピボットテーブルで表示


    ピボット軸は任意に設定可能(!)


    目標対比、移行率など各種の数値を

    最適なUIで表示


    フィルタ、ソート、並び替えなど

    直感的な操作で高度な分析

    View full-size slide

  14. どれだけ複雑か? - シート機能
    セルをクリックすると

    ドリルダウンできる(!)


    一覧表示、円グラフ表示

    時系列グラフなどで更なる分析


    セル選択、コピペや絞り込みなど、

    スプレッドシート以上のUX
    一覧表示で書き込みができる(!?)


    View full-size slide

  15. どれだけ複雑か? - And More...
    ここには書ききれない機能、また秘密な新機能がたくさん!


    興味ある方、ぜひお話ししましょう! We are hiring!

    View full-size slide

  16. Modular Monolith

    in the Real World

    View full-size slide

  17. 実際の設計紹介 - 垂直分割?水平分割?
    垂直分割:ドメインごとに分割

    水平分割:レイヤーごとに分割


    Q. 我々は?

    A.
    世間的にはモジュラーモノリス=垂直分割が一般的?

    一般のイメージとはやや異なる設計かも


    特に、複雑なドメインロジックを外に独立させているの
    がお気に入り
    どちらでも分割。必要な粒度で分割

      +コアロジックを外に抽出


    PRESENTATION1
    INFRA1 INFRA2
    APPLICATION2
    MODULE1
    MODULE2
    PRESENTATION2
    DB1 DB2
    サービス1 サービス2
    なんか複雑な

    ドメインロジック

    View full-size slide

  18. 実際の設計紹介 - モジュール構成
    Turborepoを使ったモノレポ構成

    現在35パッケージ(!)

    ※ちょっとやりすぎた感はある


    common以下でフロントエンド・バッ
    クエンド共通のロジックを格納

    複雑なドメインロジックはcommon

    View full-size slide

  19. 実際の設計紹介 - 構成方法
    モジュールごとにpackage.jsonを定義

    mainにindex.tsを指定


    index.tsにexportしたい関数を書く

    → モジュール外にexportしたくない関数はexportされ
    ない(カプセル化)

    → これが地味に良い。関数名を長くしなくて良い


    ドメインロジックのモジュールは依存
    パッケージはほぼなし。ピュアな関数で
    構成。

    View full-size slide

  20. 実際の設計紹介 - 実装
    アプリからは「モジュールを呼び出して
    組み合わせる」ような体感で処理をする


    (例)Webサーバーでの処理例

    ・authモジュールで認証

    ・featuresモジュールで権限チェック

    ・coreのドメインロジックを呼び出し

    ・infraからdbを呼んで永続化


    ※イメージを伝えるために単純化した例です。実際の
    コードとは異なります

    View full-size slide

  21. 実際やってみてどうか - 良かったところ
    ・非常に気に入っている。常に頭の中が整理されている気持ち。

      を強く持てる


    ・依存関係を強制し、レイヤーを明確にできる。

    「infraからpresentationは参照できない」など


    ・凝集度が高い。ドメインロジックを一箇所にまとめられる。

    複雑なサービスが、複数のモジュールから構成されている感覚
    「どこに書くか」ではなく「書くべき場所に書く」

    View full-size slide

  22. 実際やってみてどうか - 悪かったところ
    ・buildとlint のパフォーマンスが悪い

     主目的のためにはYarn Workspaceを使ったモジュール構成の必然性はそこまでないの
    で eslint-plugin-import-access を使う構成に変更を検討中


    ・初期構築の難易度が多少高い


    ・新規メンバーのキャッチアップには、良くも悪くもあまり影響していない…?

    (全体像を整理したくなるくらいのドメイン理解度がないと、モノリスと同じ?)


    「モノレポ」の恩恵は大きい。コードジャンプしていくだけで全部把握できる

    (=マイクロサービスだと受けづらい恩恵)

    View full-size slide

  23. まとめ
    ・SALESCOREでは、複雑なサービス開発のため、初期からモジュラーモノリスで開発


    ・複雑なサービスを複数のモジュールにより開発するスタイルは、

     
    ・build、lintのパフォーマンス、初期構築の難易度など、デメリットは多少ある


    ・「モジュール分割することに綺麗さ/メリットを感じられる人向け」なので

     分割する必要性を感じないのであれば、分割しなくて良さそう (元も子もない)

    (が、個人的には流行ってほしい開発スタイル)
    個人的にはもはや必須な開発スタイル


    View full-size slide

  24. Appendix - vsモノリス、vsマイクロサービス
    「モノリスよりも分割されていて、マイクロサービスほど分割されていない」

    のがモジュラーモノリス


    マイクロサービスだとサービス分割したときの不可逆性が強すぎる。

    モジュラーモノリスだと気軽にモジュールを作れる。


    銀の弾丸はない。常にモジュラーモノリスが良いわけではない。

    「選択肢の1つ」として持つべき
    ちょうど良い

    View full-size slide

  25. Appendix - 技術スタックの変遷
    2019- Rails, Nuxt.jsで開発。2週間でMVPを作った。週0.5くらいで開発していた時代


    2021- フルコミット開始。Next.js + Node.js (Nexus) に移行。

       初期はフロントエンド・バックエンドをリポジトリ分割。

       それぞれTypeScript Project Referencesを使ったモジュール構成


    2022- Turborepoを使ったモノレポ・モジュラーモノリスに移行


    2023春 二人目のエンジニア、PdM、デザイナーがジョイン!

       (逆に、ここまでずっと一人開発)

    View full-size slide