Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
TypeScriptとモジュラーモノリスで挑む複雑なWebアプリケーション開発
Search
Katsuma Narisawa
July 25, 2023
Programming
5
5.4k
TypeScriptとモジュラーモノリスで挑む複雑なWebアプリケーション開発
Katsuma Narisawa
July 25, 2023
Tweet
Share
More Decks by Katsuma Narisawa
See All by Katsuma Narisawa
高単価案件で働くための心構え
nullnull
0
250
乾・岡崎研究室で学んだ大切なこと
nullnull
0
1k
日本中のカップルを支える技術
nullnull
0
600
Other Decks in Programming
See All in Programming
OTP を自動で入力する裏技
megabitsenmzq
0
100
CSC307 Lecture 13
javiergs
PRO
0
320
CSC307 Lecture 14
javiergs
PRO
0
470
GC言語のWasm化とComponent Modelサポートの実践と課題 - Scalaの場合
tanishiking
0
110
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
450
Goの型安全性で実現する複数プロダクトの権限管理
ishikawa_pro
2
310
Codexに役割を持たせる 他のAIエージェントと組み合わせる実務Tips
o8n
4
1.3k
New in Go 1.26 Implementing go fix in product development
sunecosuri
0
430
社内規程RAGの精度を73.3% → 100%に改善した話
oharu121
13
8k
「やめとこ」がなくなった — 1月にZennを始めて22本書いた AI共創開発のリアル
atani14
0
380
20260313 - Grafana & Friends Taipei #1 - Kubernetes v1.36 的開發雜記:那些困在 Alpha 加護病房太久的 Metrics
tico88612
0
180
猫の手も借りたい!ので AIエージェント猫を作って社内に放した話 Claude Code × Container Lambda の Slack Bot "DevNeko"
naramomi7
0
260
Featured
See All Featured
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
250
Leo the Paperboy
mayatellez
4
1.5k
The Invisible Side of Design
smashingmag
302
51k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
640
Thoughts on Productivity
jonyablonski
75
5.1k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
120
jQuery: Nuts, Bolts and Bling
dougneiner
65
8.4k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
2.4k
SEO for Brand Visibility & Recognition
aleyda
0
4.4k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.1k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
210
Transcript
TypeScriptと モジュラーモノリスで挑む 複雑なWebアプリケーション開発 2023年7月25日 モジュラモノリス徹底解剖〜実践者から学ぶLunch LT〜 成澤 克麻 SALESCORE株式会社 CTO
Katsuma Narisawa 東北大学で自然言語処理 → 株式会社ディー・エヌ・エー → 株式会社ラブグラフ → フリーランス →
SALESCORE株式会社のCTO 直近はTypeScript, GraphQL, Prisma, Recoil, Turborepoあたりが好き 趣味:食、酒、旅、写真、漫画
最近noteがバズりました 2300+スキ!1100+はてブ!感謝!
見覚えのある単価…
Why Monolith? Modular
Why Monolith? Modular A. 複雑なサービスを 作り上げるため
一つのことを行い またそれをうまくやるプログラムを書け 協調して動くプログラムを書け
複雑なサービスを、1つ1つのシンプルな 「モジュール」を組み合わせて作り上げる なんか色々なロジック… 色んなことをやるモノリス モジュラーモノリス INFRA AUTH INFRA2 COMMON DOMAIN2
APP DOMAIN1 PRESENTATION1 PRESENTATION2
会社紹介 & 開発体制 社名:SALESCORE株式会社 事業内容:営業ドメインでSaaSとコンサル 創業メンバーの出身企業 キーエンス、DeNA 現在の開発メンバーの出身企業 DeNA、PFN、LINE、Tesla、PLAID、Yahoo 4年ほど一人開発
今年からPdM、デザイナー、エンジニアx3が増えました(詳細はAppendix)
営業組織向けSaaSを謳いつつ、中身は 任意のデータを、任意の形で可視化・編集できるサービス セールスイネーブルメントの実現には 様々なレイヤーの大小様々な支援が必要 → つまり、非常に複雑…!! ※営業ドメイン、意外と面白いよ!PRレビューみたいなのがあったり。 ぜひnote読んでください。 「ドメイン特化型Full-Stack Data
Platform」 「推測するな、計測せよ」 サービス紹介
どれだけ複雑か? - 一般的なデータパイプライン Data Source ELT TRANSFORM DWH BI REVERSE-ETL
User SALESFORCE
どれだけ複雑か? - SALESCOREのデータパイプライン Data Source ELT TRANSFORM DWH BI SHEET
REVERSE-ETL User SALESFORCE →普通は複数サービスでやることを単一サービスで実現
どれだけ複雑か? - ダッシュボード機能 ユーザー設定のKPI(集計条件)を ピボットテーブルで表示 ピボット軸は任意に設定可能(!) 目標対比、移行率など各種の数値を 最適なUIで表示 フィルタ、ソート、並び替えなど 直感的な操作で高度な分析
どれだけ複雑か? - シート機能 セルをクリックすると ドリルダウンできる(!) 一覧表示、円グラフ表示 時系列グラフなどで更なる分析 セル選択、コピペや絞り込みなど、 スプレッドシート以上のUX 一覧表示で書き込みができる(!?)
どれだけ複雑か? - And More... ここには書ききれない機能、また秘密な新機能がたくさん! 興味ある方、ぜひお話ししましょう! We are hiring!
Modular Monolith in the Real World
実際の設計紹介 - 垂直分割?水平分割? 垂直分割:ドメインごとに分割 水平分割:レイヤーごとに分割 Q. 我々は? A. 世間的にはモジュラーモノリス=垂直分割が一般的? 一般のイメージとはやや異なる設計かも
特に、複雑なドメインロジックを外に独立させているの がお気に入り どちらでも分割。必要な粒度で分割 +コアロジックを外に抽出 PRESENTATION1 INFRA1 INFRA2 APPLICATION2 MODULE1 MODULE2 PRESENTATION2 DB1 DB2 サービス1 サービス2 なんか複雑な ドメインロジック
実際の設計紹介 - モジュール構成 Turborepoを使ったモノレポ構成 現在35パッケージ(!) ※ちょっとやりすぎた感はある common以下でフロントエンド・バッ クエンド共通のロジックを格納 複雑なドメインロジックはcommon
実際の設計紹介 - 構成方法 モジュールごとにpackage.jsonを定義 mainにindex.tsを指定 index.tsにexportしたい関数を書く → モジュール外にexportしたくない関数はexportされ ない(カプセル化) →
これが地味に良い。関数名を長くしなくて良い ドメインロジックのモジュールは依存 パッケージはほぼなし。ピュアな関数で 構成。
実際の設計紹介 - 実装 アプリからは「モジュールを呼び出して 組み合わせる」ような体感で処理をする (例)Webサーバーでの処理例 ・authモジュールで認証 ・featuresモジュールで権限チェック ・coreのドメインロジックを呼び出し ・infraからdbを呼んで永続化
※イメージを伝えるために単純化した例です。実際の コードとは異なります
実際やってみてどうか - 良かったところ ・非常に気に入っている。常に頭の中が整理されている気持ち。 を強く持てる ・依存関係を強制し、レイヤーを明確にできる。 「infraからpresentationは参照できない」など ・凝集度が高い。ドメインロジックを一箇所にまとめられる。 複雑なサービスが、複数のモジュールから構成されている感覚
「どこに書くか」ではなく「書くべき場所に書く」
実際やってみてどうか - 悪かったところ ・buildとlint のパフォーマンスが悪い 主目的のためにはYarn Workspaceを使ったモジュール構成の必然性はそこまでないの で eslint-plugin-import-access を使う構成に変更を検討中
・初期構築の難易度が多少高い ・新規メンバーのキャッチアップには、良くも悪くもあまり影響していない…? (全体像を整理したくなるくらいのドメイン理解度がないと、モノリスと同じ?) 「モノレポ」の恩恵は大きい。コードジャンプしていくだけで全部把握できる (=マイクロサービスだと受けづらい恩恵)
まとめ ・SALESCOREでは、複雑なサービス開発のため、初期からモジュラーモノリスで開発 ・複雑なサービスを複数のモジュールにより開発するスタイルは、 ・build、lintのパフォーマンス、初期構築の難易度など、デメリットは多少ある ・「モジュール分割することに綺麗さ/メリットを感じられる人向け」なので 分割する必要性を感じないのであれば、分割しなくて良さそう (元も子もない) (が、個人的には流行ってほしい開発スタイル) 個人的にはもはや必須な開発スタイル
Appendix - vsモノリス、vsマイクロサービス 「モノリスよりも分割されていて、マイクロサービスほど分割されていない」 のがモジュラーモノリス マイクロサービスだとサービス分割したときの不可逆性が強すぎる。 モジュラーモノリスだと気軽にモジュールを作れる。 銀の弾丸はない。常にモジュラーモノリスが良いわけではない。 「選択肢の1つ」として持つべき ちょうど良い
Appendix - 技術スタックの変遷 2019- Rails, Nuxt.jsで開発。2週間でMVPを作った。週0.5くらいで開発していた時代 2021- フルコミット開始。Next.js + Node.js
(Nexus) に移行。 初期はフロントエンド・バックエンドをリポジトリ分割。 それぞれTypeScript Project Referencesを使ったモジュール構成 2022- Turborepoを使ったモノレポ・モジュラーモノリスに移行 2023春 二人目のエンジニア、PdM、デザイナーがジョイン! (逆に、ここまでずっと一人開発)