Slide 1

Slide 1 text

社内共通ルールを 値オブジェクトにして 社内ライブラリとして 運用してみた話 レバテック株式会社 CTO室 / テックリード / 河村 勇樹

Slide 2

Slide 2 text

| © Leverages inc. 2 ● 所属: ○ レバテック CTO室 テックリード ● 経歴: ○ 2019年4月 大手Web企業 新卒入社 ○ 2021年1月 レバレジーズ株式会社 中途入社 ● 業務: ○ システム戦略作り / アーキテクト / 採用 / 技術広報 ○ R&D(最近はTiDBの導入検証を進めています) ● 趣味: ○ お酒・ゴルフ 自己紹介 Introduction かわうそ @_syoryu89

Slide 3

Slide 3 text

今日、お伝えする内容 サマリ

Slide 4

Slide 4 text

AシステムのHogeくん XシステムのFugaくん メアドのValidationを 新しくするぜ〜

Slide 5

Slide 5 text

AシステムのHogeくん XシステムのFugaくん Aシステムから 変なフォーマットの メアドが連携された...

Slide 6

Slide 6 text

AシステムのHogeくん XシステムのFugaくん メアドのValidationを Xシステムに合わせるぞ〜

Slide 7

Slide 7 text

AシステムのHogeくん ZシステムのPiyoくん Aシステムから 変なフォーマットの メアドが連携された...

Slide 8

Slide 8 text

AシステムのHogeくん え!? どれに合わせればいいの? てか、 正解となるルールはどれ? ドキュメントはどこ?

Slide 9

Slide 9 text

ルール策定・統一しよう!!! っていうお話になります笑

Slide 10

Slide 10 text

| © Leverages inc. 10 1. レバテックについて 2. 当時のシステム事情 3. ルール策定・統一に向けて行ったこと 4. まとめ アジェンダ INDEX

Slide 11

Slide 11 text

| © Leverages inc. 11 ● 本日、割愛させていただくこと ○ システムとしての根本的な課題の内容 ○ サブシステムやマイクロサービスの仕様 ○ 値オブジェクトのルール内容の公開 ● 参考資料 ○ プロダクトを伸ばし続けるために技術的負債と改めて向き合ってみた。 ○ 「日本を、IT先進国に。」に向けて、レバテックCTO室を設立。 ○ マイクロサービス化を中心においた技術刷新とその狙い 事前にお伝えしておきたいこと 事前共有

Slide 12

Slide 12 text

1. レバテックについて

Slide 13

Slide 13 text

| © 2023 Levtech Co., Ltd. 13 | © 2023 Levtech Co., Ltd. 13 日本を、 IT先進国に。 日本を、どこよりも進んだ IT技術を持つ国にする。 そして、ここで生まれた IT人材や組織の力が、 世界中のすべての課題を、 解決する。 それが、レバテックが 叶えたい未来です。 VISION

Slide 14

Slide 14 text

| © 2023 Levtech Co., Ltd. 14 | © 2023 Levtech Co., Ltd. 14 事業ポートフォリオ Product エージェント プログラミング スクール コンテンツ メディア プラット フォーム ダイレクト リクルーティング ITエンジニア・クリエイターの フリーランス・転職・就職・教育の すべてを備える採用プラットフォーム エージェントを中心に、求人媒体、 プログラミング教育まで IT専門職のキャリアを厚くサポート。

Slide 15

Slide 15 text

2. 当時のシステム事情

Slide 16

Slide 16 text

| © 2023 Levtech Co., Ltd. 16 | © 2023 Levtech Co., Ltd. 16 ● レバテックは中規模なシステム ○ GitHubのリポジトリ数は”224” ● 技術スタック ○ ”TypeScript”がメイン ○ PHPのシステムが一部あり ● ”技術的負債”は絶賛解消中 ○ 密結合なシステム ○ 非構造化データ ○ マスタデータの分散 ○ … システムの現状 2. 当時のシステム事情 プロダクトを伸ばし続けるために技術的負債と改めて向き合ってみた。

Slide 17

Slide 17 text

| © 2023 Levtech Co., Ltd. 17 | © 2023 Levtech Co., Ltd. 17 レバテック(サービス)の大まかな仕組み 2. 当時のシステム事情

Slide 18

Slide 18 text

| © 2023 Levtech Co., Ltd. 18 | © 2023 Levtech Co., Ltd. 18 レバテック(サービス)の大まかな仕組み 2. 当時のシステム事情 エンジニアと企業をマッチング

Slide 19

Slide 19 text

| © 2023 Levtech Co., Ltd. 19 | © 2023 Levtech Co., Ltd. 19 レバテック(サービス)の大まかな仕組み 2. 当時のシステム事情

Slide 20

Slide 20 text

| © 2023 Levtech Co., Ltd. 20 | © 2023 Levtech Co., Ltd. 20 レバテック(サービス)の大まかな仕組み 2. 当時のシステム事情 集める=会員登録 → コアドメイン

Slide 21

Slide 21 text

| © 2023 Levtech Co., Ltd. 21 | © 2023 Levtech Co., Ltd. 21 ● レバテックにおいて「登録」という機能はなくてはならないもの ○ この機能が停止するとサービスとしての価値提供が難しくなる ● 「登録」のプロセスにおいて重要な情報を取得している ○ 名前、生年月日、メールアドレス、電話番号などの個人情報 ● 各システムに連携できないと、ユーザーに価値提供ができない ○ 登録情報をなんとしても”確実”にすべてのシステムに連携をしたい 会員登録 = コアドメイン 2. 当時のシステム事情

Slide 22

Slide 22 text

| © 2023 Levtech Co., Ltd. 22 | © 2023 Levtech Co., Ltd. 22 登録に関わるシステムの概要 2. 当時のシステム事情

Slide 23

Slide 23 text

| © 2023 Levtech Co., Ltd. 23 | © 2023 Levtech Co., Ltd. 23 登録に関わるシステムの概要 2. 当時のシステム事情 会員登録だけで10個以上のシステムが関わる

Slide 24

Slide 24 text

| © 2023 Levtech Co., Ltd. 24 | © 2023 Levtech Co., Ltd. 24 ● 会員登録だけで”10個以上”のシステムが関わる ○ 各システム / サブシステム / マイクロサービス / etc. ● 営業支援システムとの連携 ○ 末端のシステムでもあり、ユーザー・業務への影響もかなり大きい ● そもそもの設計が良くない(小声...) ○ いわゆる「分散されたモノリス」みたいな状態に近い 会員登録だけでも関わるシステムが多い... 2. 当時のシステム事情

Slide 25

Slide 25 text

| © 2023 Levtech Co., Ltd. 25 | © 2023 Levtech Co., Ltd. 25 どんな問題が発生したかというと... 分散されたシステムはしんどい...笑

Slide 26

Slide 26 text

| © 2023 Levtech Co., Ltd. 26 | © 2023 Levtech Co., Ltd. 26 ● 1つでもルール(Validation)を変更するとシステム障害になる ○ 例えば: ■ とあるシステムでValidationのライブラリを変更 ■ 変更時、デフォルトの設定のままでリリース ■ システム連携間でドメインパート部分で予期せぬエラーが発生... ● 正しいルールに修正したいが、正解となるドキュメントが存在しない ○ 例えば: ■ AシステムはXルールだけど、BシステムはYルールです ○ さらに: ■ 各システムを見てみると”すでに”ルールが違うところを発見することも... どんな問題が発生したか 2. 当時のシステム事情

Slide 27

Slide 27 text

| © 2023 Levtech Co., Ltd. 27 | © 2023 Levtech Co., Ltd. 27 ● 1つでもルール(Validation)を変更するとシステム障害になる ○ 例えば: ■ とあるシステムでValidationのライブラリを変更 ■ 変更時、デフォルトの設定のままでリリース ■ システム連携間でドメインパート部分で予期せぬエラーが発生... ● 正しいルールに修正したいが、正解となるドキュメントが存在しない ○ 例えば: ■ AシステムはXルールだけど、BシステムはYルールです ○ さらに: ■ 各システムを見てみると”すでに”ルールが違うところを発見することも... どんな問題が発生したか 2. 当時のシステム事情

Slide 28

Slide 28 text

| © 2023 Levtech Co., Ltd. 28 | © 2023 Levtech Co., Ltd. 28 ● 1つでもルール(Validation)を変更するとシステム障害になる ○ 例えば: ■ とあるシステムでValidationのライブラリを変更 ■ 変更時、デフォルトの設定のままでリリース ■ システム連携間でドメインパート部分で予期せぬエラーが発生... ● 正しいルールに修正したいが、正解となるドキュメントが存在しない ○ 例えば: ■ AシステムはXルールだけど、BシステムはYルールです ○ さらに: ■ 各システムを見てみると”すでに”ルールが違うところを発見することも... どんな問題が発生したか 2. 当時のシステム事情 ルールを策定して統一しよう! そのルールをライブラリとして配布しよう!

Slide 29

Slide 29 text

| © 2023 Levtech Co., Ltd. 29 | © 2023 Levtech Co., Ltd. 29 ● 1つでもルール(Validation)を変更するとシステム障害になる ○ 例えば: ■ とあるシステムでValidationのライブラリを変更 ■ 変更時、デフォルトの設定のままでリリース ■ システム連携間でドメインパート部分で予期せぬエラーが発生... ● 正しいルールに修正したいが、正解となるドキュメントが存在しない ○ 例えば: ■ AシステムはXルールだけど、BシステムはYルールです ○ さらに: ■ 各システムを見てみると”すでに”ルールが違うところを発見することも... どんな問題が発生したか 2. 当時のシステム事情

Slide 30

Slide 30 text

| © 2023 Levtech Co., Ltd. 30 | © 2023 Levtech Co., Ltd. 30 ● 1つでもルール(Validation)を変更するとシステム障害になる ○ 例えば: ■ とあるシステムでValidationのライブラリを変更 ■ 変更時、デフォルトの設定のままでリリース ■ システム連携間でドメインパート部分で予期せぬエラーが発生... ● 正しいルールに修正したいが、正解となるドキュメントが存在しない ○ 例えば: ■ AシステムはXルールだけど、BシステムはYルールです ○ さらに: ■ 各システムを見てみると”すでに”ルールが違うところを発見することも... どんな問題が発生したか 2. 当時のシステム事情 そのルール(ライブラリ)をドキュメント化しよう!

Slide 31

Slide 31 text

| © Leverages inc. 31 ● レバテックにおいて”会員登録”は重要な機能 ○ 重要な情報を取しており、すべてのシステムに”確実”に連携する必要がある ● 会員登録だけで”10個以上”のシステムが関わる ○ 根本的な問題はさておき... ● 登録情報のルールを一部変更するとシステム障害になってしまう ○ 正解となるドキュメントも存在しない... ● そこで、ルール策定・統一しよう! ○ 社内ライブラリを作成して実現して、ルール(ライブラリ)をドキュメント化しよう! ここまでのまとめ 2. 当時のシステム事情

Slide 32

Slide 32 text

3. ルール策定・統一に向けて行ったこと

Slide 33

Slide 33 text

| © Leverages inc. 33 ● 初期段階でルール化(=値オブジェクト)にするスコープ ○ 登録に関わる情報 ■ 「メールアドレス」「電話番号」「生年月日」「姓名」「姓名かな」「姓名カナ」 ● ”ルールの策定と統一”を最優先で進めました ○ 理想のルールも定義できたが、まずはルールの策定と統一を優先 ● 値オブジェクトを独自ルールにする場合、どのシステムに合わせるか ○ 基本的には連携において「末端のシステム」に合わせる ■ 理想のルールを合わせるにも独自ルールが多かったため ● 登録におけるシステム連携間の統合テストを作成 ○ 本日は割愛 進める前の準備と前提の整理 3. ルール策定・統一に向けて行ったこと

Slide 34

Slide 34 text

技術的負債に立ち向かうためにテストを書いてる話

Slide 35

Slide 35 text

| © Leverages inc. 35 2.1. 値オブジェクトのルール策定 2.2. 値オブジェクトのライブラリ化 2.3. 値オブジェクトのドキュメント化 2.4. 値オブジェクトのルール統一 ※ ルールを値オブジェクトに実装 ※ 「メールアドレス」に絞ってます 手順 3. ルール策定・統一に向けて行ったこと

Slide 36

Slide 36 text

| © Leverages inc. 36 2.1. 値オブジェクトのルール策定 2.2. 値オブジェクトのライブラリ化 2.3. 値オブジェクトのドキュメント化 2.4. 値オブジェクトのルール統一 ※ ルールを値オブジェクトに実装 ※ 「メールアドレス」に絞ってます 手順 3. ルール策定・統一に向けて行ったこと

Slide 37

Slide 37 text

| © Leverages inc. 37 ● 一般的な「メールアドレス」のルールはどうなるべきなのか? ○ メールアドレスの国際基準「RFC」 ■ RFCはIETFによる技術仕様の保存、公開形式 ○ メールアドレスに関連する文書に当たるのが「RFC5321」「RFC5322」 ■ 「RFC5321」 ● Simple Mail Transfer Protocol(SMTP)に関連するもの ● メールの送信に関する基本的なプロトコルを規定 ● Last updated 2020-01-21 ■ 「RFC5322」 ● Internet Message Format(メールのフォーマット)に関するもの ● メールメッセージの構造やヘッダー形式などを定義 ● Last updated 2020-01-21 「メールアドレス」におけるルール策定 - 一般化できるか? 2.1. 値オブジェクトのルール策定

Slide 38

Slide 38 text

| © Leverages inc. 38 ● TypeScriptで普及しているライブラリ「zod」をみてみると... ○ まさかのIssue(Discussionsも)発見w ■ RFC: Refactoring transformers and Zod 3 ■ What is RFC No of the email validator? ○ 少し読み解いてみると... ■ RFCは実用上は不十分 ■ それを補完するUASG-28が存在 ■ UASG-28を実現するには、プログラミング言語に応じて違う ● 参考 → ZodのメールバリデーションはRFCのどこまで準拠している? ● (zodでこんな話が出ることは、他のライブラリも厳しいのでは?笑) 世の中のライブラリは「RFC」に対応しているのか? 2.1. 値オブジェクトのルール策定

Slide 39

Slide 39 text

| © Leverages inc. 39 ● TypeScriptで普及しているライブラリ「zod」をみてみると... ○ まさかのIssue(Discussionsも)発見w ■ RFC: Refactoring transformers and Zod 3 ■ What is RFC No of the email validator? ○ 少し読み解いてみると... ■ RFCは実用上は不十分 ■ それを補完するUASG-28が存在 ■ UASG-28を実現するには、プログラミング言語に応じて違う ● 参考 → ZodのメールバリデーションはRFCのどこまで準拠している? ● (zodでこんな話が出ることは、他のライブラリも厳しいのでは?笑) 世の中のライブラリは「RFC」に対応しているのか? 2.1. 値オブジェクトのルール策定 一般化できなかった(オワタw)

Slide 40

Slide 40 text

| © Leverages inc. 40 ● 一般的なルールに当てはめるのは諦めました... ○ 最新のメンテナンスが実行できていないシステムがあるため ■ Last updated 2020-01-21よりも古い状態もいくつか存在 ○ 世の中のライブラリが「メールアドレス」も対応しきれていない ■ TypeScriptで普及しているライブラリ「zod」もその一例 ■ UASG-28を実現するには、プログラミング言語に応じて違う ● 「メールアドレス」を利用しているすべてのシステムを調査して策定 ■ 調査対象: ● 最大文字列長・最小文字列長・正規表現 ■ 方針 ● 「末端のシステム」のルールに合わせる(られるようにする) 「メールアドレス」におけるルール策定 - 独自ルールの策定 2.1. 値オブジェクトのルール策定

Slide 41

Slide 41 text

| © Leverages inc. 41 ● 策定したルールは値オブジェクトで扱う ○ Stringなどのプリミティブ型としては扱わない ■ 振る舞いなどを持つためにオブジェクトで表現 ● Validationはどこでやるのか? ○ コンストラクタで行う ■ ルールから逸脱した値オブジェクトを生成させないため ● 例外をthrowした場合はどのような挙動にするか? ○ Result型など値を返さない ■ ルールから逸脱したまま、処理を継続させないため 「メールアドレス」における実際のモデリング 2.1. 値オブジェクトのルール策定

Slide 42

Slide 42 text

| © Leverages inc. 42 2.1. 値オブジェクトのルール策定 2.2. 値オブジェクトのライブラリ化 2.3. 値オブジェクトのドキュメント化 2.4. 値オブジェクトのルール統一 ※ ルール=値オブジェクト ※ 「メールアドレス」に絞ってます 手順 3. ルール策定・統一に向けて行ったこと

Slide 43

Slide 43 text

| © Leverages inc. 43 ● TypeScriptを利用してnpmパッケージを作成 ○ Bundlerとしてtsupを利用 ○ (最近はtsupを利用することが多いですね) ● 値オブジェクトは基底クラスを設けて汎用化 ○ structural subtypingを回避するため ○ Validation発生時にThrowさせたいため ● 単体テストを作成してルールを担保する ○ ”メールアドレスのValidation仕様=単体テストの結果” ライブラリ化に向けてやったこと 2.2. 値オブジェクトのライブラリ化

Slide 44

Slide 44 text

| © Leverages inc. 44 ● 構造的部分型(Structural Subtyping) ○ TypeScriptで採用されている定義 ○ シグネチャが等しければ置換可能 ● 構造的部分型の回避 ○ 値オブジェクトは同一性を構造で判断しない ○ 値オブジェクトに名前を与えること(Branded Types)で回避 ● Validation実行時はThrowさせる ○ ルール統一が目的なので、ルールから逸脱した値は許容しない 値オブジェクトは基底クラスを設けて汎用化 2.2. 値オブジェクトのライブラリ化

Slide 45

Slide 45 text

| © Leverages inc. 45 メールアドレス(値オブジェクト)の一例 2.2. 値オブジェクトのライブラリ化 値オブジェクトの基底クラス ● Validationはコンストラクタで行う ● 例外をthrowした場合は値は返さない ● tryValidメソッドを実装側に強制させる メールアドレスの値オブジェクト ● Branded Types用の名前を与える ● 策定したルールからValidationを実装

Slide 46

Slide 46 text

| © Leverages inc. 46 メールアドレス(値オブジェクト)の一例 - フロントエンド 2.2. 値オブジェクトのライブラリ化 フロントエンドの場合の注意 ● Throwするとユーザー体験に影響あり ● ライブラリに合わせてValidationを実装 フロントエンド側にも導入しています ● 値オブジェクトはTypeScriptのみで実装 ● どんな環境でも導入は可能

Slide 47

Slide 47 text

| © Leverages inc. 47 単体テストを作成してルールの担保 2.2. 値オブジェクトのライブラリ化 テスト結果の出力=ルールの仕様 作成したルールを元にテストを作成

Slide 48

Slide 48 text

| © Leverages inc. 48 2.1. 値オブジェクトのルール策定 2.2. 値オブジェクトのライブラリ化 2.3. 値オブジェクトのドキュメント化 2.4. 値オブジェクトのルール統一 ※ ルール=値オブジェクト ※ 「メールアドレス」に絞ってます 手順 3. ルール策定・統一に向けて行ったこと

Slide 49

Slide 49 text

| © Leverages inc. 49 ● TypeDocを利用 ○ TypeScript製 ○ ドキュメント生成ツール ● 特徴 ○ コードの型情報を読み取ってくれる ○ TSDocのアノテーションに対応 ○ プラグイン拡張可能 ■ UIのテーマ変更など ドキュメント化 2.3. 値オブジェクトのドキュメント化

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

| © Leverages inc. 51 2.1. 値オブジェクトのルール策定 2.2. 値オブジェクトのパッケージ化 2.3. 値オブジェクトのライブラリ化 2.4. 値オブジェクトのルール統一 ※ ルール=値オブジェクト ※ 「メールアドレス」に絞ってます 手順 3. ルール策定・統一に向けて行ったこと

Slide 52

Slide 52 text

| © Leverages inc. 52 ● ルール違反している過去データのリペア ○ 現在、存在しているデータを連携する可能性があるので、データリペアを実施 ■ ※ 一度、登録したデータを使わない場合はリペア不要 ● ルール反映の順序を考慮 ○ 連携先のシステムで障害となってしまうため ○ 「末端のシステム」に合わせてルールを作成したので「先端のシステム」から反映 ● 再連携できる仕組みの構築 ○ 再連携できる仕組みがあると、障害発生時にも業務への影響を小さくできました ■ 登録→システム連携間で障害発生→データリペア→再連携実行→連携完了 ルール統一(反映)に向けて行ったこと 2.4. 値オブジェクトのルール統一

Slide 53

Slide 53 text

| © Leverages inc. 53 再連携できる仕組みの構築 2.4. 値オブジェクトのルール統一

Slide 54

Slide 54 text

| © Leverages inc. 54 再連携できる仕組みの構築 2.4. 値オブジェクトのルール統一 連携が失敗した場合はデータリペアを実行 その後、DLQからEventを取り出してEventBridgeを再実行 非同期 AND 結果整合性によるデータ連携

Slide 55

Slide 55 text

社内共通ルール(ライブラリ)の現在

Slide 56

Slide 56 text

| © Leverages inc. 56 ● 社内共通ルール(ライブラリ)化されたもの ○ 登録情報:メールアドレス、電話番号、生年月日、姓名、姓名かな、姓名カナ ○ その他:パスワード、適格請求書発行事業者の登録番号など ● 障害発生も劇的に削減できました ○ 安定版のリリースと各システムに反映できたのが2023年8月 ■ それ以降、不正なフォーマットのメールアドレス起因の障害は0件 ● ドメイン知識を集めるプロセスが構築できた ○ ルール策定・統一しようという動きによりこのルールを共通化しようという流れ 社内共通ルール(ライブラリ)の現在 3. ルール策定・統一に向けて行ったこと

Slide 57

Slide 57 text

| © Leverages inc. 57 ● 実際の値オブジェクトにより近づけたい ○ Validationぐらいしかモデリングができていない ○ 業務ルール等を反映していきたい ● 値オブジェクトだけでなくドメインオブジェクトも進めていきたい ○ 重複した業務ルールはたくさんあるので一元管理できるようにしたい ■ 特に登録のプロセスにはたくさんのルールが存在 ● なにより根本的な問題の解決を進めていきたい ○ 分散されたシステムの密結合を取り除いていかないと...笑 社内共通ルール(ライブラリ)の課題と今後 3. ルール策定・統一に向けて行ったこと

Slide 58

Slide 58 text

4. まとめ

Slide 59

Slide 59 text

| © Leverages inc. 59 ● ルール策定・統一の背景 ○ 登録情報のルールを一部の変更するとシステム障害になってしまう ○ その手段として「ルールを策定・統一」することにしました ○ その実現方法として「ライブラリ化及びドキュメント化」を行いました ● ルール策定・統一までの流れ ○ 値オブジェクトのルール策定→ライブラリ化→ドキュメント化→ルール統一 ■ 「一般化されたルール」にするのか or 「独自ルール」にするのか ■ 基底クラスと単体テストを活用 ■ TypeDocの活用によりドキュメント化を自動化 ■ 再連携できる仕組みの構築しておくと進めやすい ● 結果、障害発生も劇的に削減できました ○ ドメイン知識を集めるプロセスも構築できた 今日のまとめ 4. まとめ

Slide 60

Slide 60 text

この課題に取り組んで思ったこと

Slide 61

Slide 61 text

ルールをちゃんと決めて反映しよう! やっぱ、分散されたシステムはしんどい...笑

Slide 62

Slide 62 text

宣伝 さいごに

Slide 63

Slide 63 text

| © Leverages inc. 63 ● 🔥レバテック開発部 テックブログ🔥 ○ https://zenn.dev/p/levtech ● Leverages Tech Blog ○ https://tech.leverages.jp/ ● Speaker Deck ○ https://speakerdeck.com/leveragestech ● LevTech MeetUp(仮) ○ TS/テスト/アーキテクト/分散システム など 情報発信中です!!! 宣伝

Slide 64

Slide 64 text

ご清聴ありがとうございました!!!