Slide 1

Slide 1 text

TypeScript開発に モジュラーモノリスを持ち込む Sansan株式会社 Digitization部 Bill One Entryグループ 秋⼭ 雅之 / @aki202

Slide 2

Slide 2 text

今⽇の内容はTechBlogにしました 『🔎 typescript モジュラーモノリス』

Slide 3

Slide 3 text

2021年中途⼊社し、Bill Oneのデータ化を⽀える。 スキーマ駆動開発やモジュラーモノリスの導⼊など、 システムのリアーキテクチャをリード。 好きなPodcastは超相対性理論とコテンラジオ。 秋⼭ 雅之 Sansan株式会社 Digitization部 Bill One Entryグループ リーダブル秋⼭ @aki202

Slide 4

Slide 4 text

PR:Digitization部① 私たちは、あらゆるアナログ資産から“使えるデータ”をつくります。 顧客がDXのスタート地点に⽴つことが、私たちの存在意義です。 顧客のアナログ資産 名刺 請求書 契約書 Digitization部 データ化 顧客のDX 使えるデータ

Slide 5

Slide 5 text

PR:Digitization部② 研究開発 ビジネス職 オペレーションセンター データ化の品質・コスト・ オペレーションの管理 オペレーター(データ⼊⼒・ スキャンする⼈)の採⽤ など Bill One Entryグループ データ化 グループ 請求書データ化システム 契約書データ化 システム 請求書スキャン システム メール署名抽出 システム インフラ グループ データ化システムのインフラ基盤 名刺データ化 システム エンジニア職 Digitization部 プロダクト 開発 Sansanの 開発エンジニアなど

Slide 6

Slide 6 text

PR:Digitization部③ 名刺データ化 メール署名抽出 契約書データ化 請求書データ化 AWS インフラ ⾔語 フレームワーク ライブラリ Ruby on Rails React Sidekiq Ruby on Rails Sidekiq Ruby on Rails React Redux Express Chromatic AWS AWS Next.js MUI ReactAdmin Chakra UI FastAPI OpenCV その他ツール その他 Re:dash, CircleCI など 請求書スキャン React Semantic UI Express Fast API

Slide 7

Slide 7 text

モジュール性

Slide 8

Slide 8 text

図. アーキテクチャ特性の⼀部 引⽤:『進化的アーキテクチャ』 Neal Ford, Rebecca Parsons, Patrick Kua 著 アーキテクチャ特性

Slide 9

Slide 9 text

アーキテクチャ特性 図. アーキテクチャ特性の⼀部 引⽤:『進化的アーキテクチャ』 Neal Ford, Rebecca Parsons, Patrick Kua 著

Slide 10

Slide 10 text

モジュール性 “モジュール性は、ほとんどのアーキテクトが気にしている暗黙のアーキテ クチャ特性だ。というのも、モジュール性がうまく維持されないと、コー ドベースの構造が損なわれる可能性があるからだ。そのため、アーキテク トはモジュール性の確保に、⾼い優先度を置かなくてはならない。” 引⽤:『ソフトウェアアーキテクチャの基礎』 Mark Richards, Neal Ford 著 / 島⽥ 浩⼆ 訳

Slide 11

Slide 11 text

コード品質

Slide 12

Slide 12 text

技術的負債と開発⽣産性 図. 技術的負債と開発⽣産性 引⽤:『ソフトウェアアーキテクチャメトリクス』 Christian Ciceriら 著

Slide 13

Slide 13 text

コード品質とビジネス 図. コード品質と開発に必要な時間 引⽤:『Code Red: The Business Impact of Code Quality』 Adam Tornhillら 著

Slide 14

Slide 14 text

- コードの低品質化がビジネスに負のインパクトを与える。 - コード品質を改善する⼀つの⼿段がモジュラーモノリス。

Slide 15

Slide 15 text

モジュラーモノリス

Slide 16

Slide 16 text

モジュラーモノリスの定義 “モジュラーモノリスとは、単⼀プロセスが別々のモジュールで構成され、 それぞれ独⽴して作業できるものの、デプロイのために結合する必要があ るシステムだ。” 引⽤:『モノリスからマイクロサービスへ』 Sam Newman 著 / 島⽥ 浩⼆ 訳

Slide 17

Slide 17 text

レイヤードアーキテクチャ

Slide 18

Slide 18 text

モジュラーモノリス

Slide 19

Slide 19 text

モジュール分割の⽅針

Slide 20

Slide 20 text

- ⽅針1:モジュールにDBデータを専有させる - ⽅針2:モジュール内をレイヤードアーキテクチャとして構成する - ⽅針3:Lintルールによって実現する 3つの⽅針

Slide 21

Slide 21 text

⽅針1:モジュールにDBデータを専有させる

Slide 22

Slide 22 text

⽅針1:モジュールにDBデータを専有させる

Slide 23

Slide 23 text

例:2つのモジュールが1つのテーブルにアクセス

Slide 24

Slide 24 text

スキーマが変われば2つのモジュールも要変更

Slide 25

Slide 25 text

1個のDBテーブルは1個のモジュールに占有させる

Slide 26

Slide 26 text

モジュラーモノリスにおける結合度の概念モデル

Slide 27

Slide 27 text

共通結合をよりマシな結合度に下げる

Slide 28

Slide 28 text

補⾜:NoSQLとモジュラーモノリスの好相性 分かりすさのためにDBテーブルと表現しているが、 NoSQLであるFirestoreを使っている。 FirestoreではDBテーブルに対応するのはコレクションという概念。 Firestoreにはテーブル結合(JOIN)がないため、 むしろモジュール分離に伴うコレクションの分離が⽐較的容易だった。 JOINがないという制約がモジュラーモノリスと好相性というのは発⾒だ った。

Slide 29

Slide 29 text

⽅針2:モジュール内をレイヤードアーキテクチャに

Slide 30

Slide 30 text

⽅針3:Lint ルールによって実現する - (1) パッケージ管理ツールの workspaces 機能 - e.g., npm, yarn, pnpm - (2) モノレポ管理ツール - e.g., Turborepo, Nx - (3) Linter - e.g., ESlint, Biome

Slide 31

Slide 31 text

よく考えると達成したいことは2つだけ 1. レイヤードアーキテクチャの各レイヤーの依存⽅向に制約を設ける (e.g. domain が services に依存してはならない) 2. モジュールが明⽰的に export しているものだけを import できる

Slide 32

Slide 32 text

よく考えると達成したいことは2つだけ 1. レイヤードアーキテクチャの各レイヤーの依存⽅向に制約を設ける (e.g. domain が services に依存してはならない) 2. モジュールが明⽰的に export しているものだけを import できる どちらもLintだけで達成可能

Slide 33

Slide 33 text

モジュラーモノリスを持ち込む

Slide 34

Slide 34 text

ステップ1:単⼀のエイリアスを設定する ⛔:各モジュールにエイリアスを設ける ✅:単⼀エイリアス@m/ だけを設定 これにより各種ツールの設定必要がなくなり、フォルダを作るだけでよくなる

Slide 35

Slide 35 text

ステップ2:ESLint ルールを設定する 1. no-restricted-paths:モジュール内の依存関係を制約する 2. ⾃作ルール:モジュール同⼠の依存関係を制約する

Slide 36

Slide 36 text

1. no-restricted-paths eslint-plugin-import プラグインが 提供するルール。 import ⽂に制約を設定できる。 モジュール内の依存関係を制約する。 禁⽌

Slide 37

Slide 37 text

“モジュール外から modules//index.ts 以 外の import を禁⽌する” という単純なルール。 他の選択肢として、uhyo⽒の eslint-plugin-import-access プラグインを使う選択肢もあったが、export ⽂にアノテ ーションを書く必要があるため不採⽤にした。 2. ⾃作ルール

Slide 38

Slide 38 text

ステップ3:モジュールに切り出す あとはモジュールに切り出していくだけ。 機能開発・修正の際、その前段のリファクタリ ングとしてモジュール化できないか検討する。 モジュールの作り⽅は、左図のような設計資料 を作り、チーム内の⽬線合わせをしている。

Slide 39

Slide 39 text

成果

Slide 40

Slide 40 text

リードタイムの安定

Slide 41

Slide 41 text

● 経験的に知られていたコード品質が持つビジネスインパクトを、 裏付けるような研究が⾏われている。 ● コード品質を担保する⼿法としてモジュラーモノリスがある。 ● モジュールを括りだすガイドラインとして次の2つを設定した。 ○ (A) ドメインで分離する ○ (B) DBデータを占有するように分離する ● 各モジュールはレイヤードアーキテクチャで構成した。 ● NoSQLは、モジュールにDBデータを占有させる⽅針と相性が良い。 ● TypeScriptにおけるモジュール化には静的解析が使え、 Lintルールの設定だけでも機能する。 まとめ

Slide 42

Slide 42 text

No content