Slide 1

Slide 1 text

サイロ化した金融システムを、packwerkを 利用して無事故でリファクタリングした話 Kota Kusama 2024/10/26

Slide 2

Slide 2 text

©2024 Coincheck Inc. 2 自己紹介 Kota Kusama @mutakapi8008 ● 2022年7月にコインチェック株式会社へ入社 ○ 現在はアプリケーション基盤部に在籍 ● Rails未経験入社、Rails歴2年と少し ● 16 Personalities ○ 仲介者 - INFP型の性格 ● 最近ハマっているもの ○ ダンジョン飯 ○ 育児(アピール)

Slide 3

Slide 3 text

©2024 Coincheck Inc. 3 目次 1. バックエンド部分の現状と課題 a. 現状 b. 課題事例 2. 課題解決 a. 解決方針 b. packwerkと関連gemの説明 c. やったこと 3. 導入後の評価 a. packwerkの良い点 b. packwerkでは防ぎきれない観点の対策 c. 今後の展望 4. まとめ

Slide 4

Slide 4 text

©2024 Coincheck Inc. 4 1 バックエンド部分の現状と課題

Slide 5

Slide 5 text

©2024 Coincheck Inc. 暗号資産取引サービス「Coincheck」 5 国内最大級の顧客基盤、本人確認済210万のユーザーが利用 暗号資産取引の”ファースト口座” IEO/INOのリーディングカンパニー ● 使いやすいUI/UX ● 5年連続アプリDL数国内No.1* ● 国内IEO 6例のうち3例を実施** ● INO(Initial NFT Offering)実績4件 *対象:国内の暗号資産取引アプリ 期間:2019年1月〜2023年12月 データ協力:App Tweak **2024年9月末現在

Slide 6

Slide 6 text

©2024 Coincheck Inc. 6 現状 サービス開始から10年が経過し、プロダクトコードの規模はどんどん膨らんでいる

Slide 7

Slide 7 text

©2024 Coincheck Inc. 7 現状 複雑でモノリシックなコードとなり、下記のような状況となっている ● 適切に統一されたレイヤー化ができていない ● サービス横串の仕様整理が難しい ● ロジックに対するコードオーナーの境界線が曖昧

Slide 8

Slide 8 text

©2024 Coincheck Inc. 8 今日は1つの課題に着目してお話しします📢

Slide 9

Slide 9 text

©2024 Coincheck Inc. 9 背景 コインチェックのプロダクトは、大きく分けても10を超えている ● 日本円入出金 ● 暗号資産入出金 ● 販売所 ● 取引所 ● Coincheck IEO ● Coincheck NFT ● Coincheckつみたて ● Coincheckリワード ● Coincheck OnRamp ● Coincheckでんき・ガス ● 貸暗号資産 ● …etc

Slide 10

Slide 10 text

©2024 Coincheck Inc. 10 背景 プロダクトにより、ユーザステータスに応じた取引可否の判定が必要 ただし、判定条件はとても複雑

Slide 11

Slide 11 text

©2024 Coincheck Inc. 11 背景 事業の成長と、法令対応などの要因により判定条件が複雑化

Slide 12

Slide 12 text

©2024 Coincheck Inc. 12 課題 プロダクト毎やModel/Controllerに、40箇所以上の判定箇所が存在

Slide 13

Slide 13 text

©2024 Coincheck Inc. 13 課題 プロダクト毎やModel/Controllerに、40箇所以上の判定箇所が存在 「認可ロジックの散在」 ※ここでの認可とは、システム内部におけるユーザの取引可否の判断を意味する

Slide 14

Slide 14 text

©2024 Coincheck Inc. 14 課題:認可ロジックの散在 下記のような問題が顕在化 ● サービス横串の仕様がわかりにくい ● 認可ロジックの妥当性を確認するコストが高い ● ドメインロジックが複雑化する

Slide 15

Slide 15 text

©2024 Coincheck Inc. 15 2 課題解決

Slide 16

Slide 16 text

©2024 Coincheck Inc. 16 解決方針 基本的な解決方針は以下のとおり ● IFの統一 ● 認可ロジックの集約

Slide 17

Slide 17 text

©2024 Coincheck Inc. 17 どう集約するべきか🤔

Slide 18

Slide 18 text

©2024 Coincheck Inc. 18 どう集約するべきか 前提:サイロ化した金融システムの難しさ ● インシデントは金融庁報告へと繋がる ● 多くのドメインが存在し影響範囲が広い →最初のステップとしてアーキテクチャをなるべく大きく変更せずに集約したい

Slide 19

Slide 19 text

©2024 Coincheck Inc. 19 どう集約するべきか 以下の要因からモジュラーモノリス構造を選択 ● マイクロサービス? ○ 現状のDB構成や、アーキテクチャ変更による品質担保の観点から非現実的 ○ ある程度のコードの視認性は維持しておきたい ● 共通クラス? ○ 共通クラス化はされている部分もあった ○ 使用方法の不明確さやドメイン毎の仕様により、クラス内にメソッドが乱立する状態に ● モジュラーモノリス ○ インフラ部分に影響することなく構成を試すことができる ○ 関心の分離を行いつつ、一定の視認性を維持することができる

Slide 20

Slide 20 text

©2024 Coincheck Inc. 20 どう集約するべきか 以下の要因からpackwerkを採用 ● 実態は静的解析なので本番に影響を与えない ● 依存関係の検知ができる ● パブリックアクセス領域の設定 ○ 不必要なロジックへの参照を制限できる ● コード移動のみでモジュール化が実現できて認知負荷が低め ○ Railsエンジンも同じメリットはあるものの、上述の依存検知、パブリック領域設定の点で優位

Slide 21

Slide 21 text

©2024 Coincheck Inc. 21 packwerkとは?📦

Slide 22

Slide 22 text

©2024 Coincheck Inc. 22 packwerkとは Railsアプリケーションのモジュラーモノリス化を支援する静的解析ツール

Slide 23

Slide 23 text

©2024 Coincheck Inc. 23 packwerkとは Railsアプリケーションのモジュラーモノリス化を支援する静的解析ツール ● packwerk checkして

Slide 24

Slide 24 text

©2024 Coincheck Inc. 24 packwerkとは Railsアプリケーションのモジュラーモノリス化を支援する静的解析ツール ● packwerk checkして ● 違反を検知 違反なし󰢏 違反あり󰢃

Slide 25

Slide 25 text

©2024 Coincheck Inc. 25 packwerkとは packwerkは、package.ymlが置かれたディレクトリ配下を1つのパッケージと認識 accountingパッケージ authorizationパッケージ

Slide 26

Slide 26 text

©2024 Coincheck Inc. 26 packwerkとは packwerkは、package.ymlが置かれたディレクトリ配下を1つのパッケージと認識 accountingパッケージ authorizationパッケージ package.ymlの中には検知する 違反の設定を記述

Slide 27

Slide 27 text

©2024 Coincheck Inc. 27 packwerkとは packwerk自身は、依存関係の違反を検知する authorizationパッケージ accountingパッケージ package.ymlで依存が認められて いなければ、違反として検知

Slide 28

Slide 28 text

©2024 Coincheck Inc. 28 packwerkとは packwerk自身は、依存関係の違反を検知する authorizationパッケージ accountingパッケージ package.ymlで依存が認められて いなければ、違反として検知 認可ロジックのパッケージ化ではモノリス側(Userモデルなど)への依存が存在 →今回は依存関係を排除したい目的ではない為、依存は許容する

Slide 29

Slide 29 text

©2024 Coincheck Inc. 29 関連gem:packwerk-extensions packwerkで検知する違反を拡充させるgem ● メインはプライバシーチェッカー ● パッケージ内にパブリック領域/パブリッククラスの定義を行い、非パブリック領域へ の参照を違反として検知 ● パブリック領域の定義方法は下記 ○ publicディレクトリ内にコード類を配置する ○ ファイルの先頭5行に宣言コメントを追加 認可ロジックへの直接参照を制限する目的で、この違反検知を有効化している

Slide 30

Slide 30 text

©2024 Coincheck Inc. 30 関連gem:packs-rails パッケージ化したコード類を自動的にzeitwerkのオートロードパスに乗せてくれるgem パッケージ追加毎に手動でパス追加 する必要がなくなる デフォルトでpacks配下のパッケージを パスに追加してくれる

Slide 31

Slide 31 text

©2024 Coincheck Inc. 31 やったこと💪

Slide 32

Slide 32 text

©2024 Coincheck Inc. 32 やったこと 認可ロジックを集約した認可パッケージの作成を行うことで課題を解決 ● ユーザーが特定の取引を実施できるか否かを返却するクラスを作成し、IFを1つに統一 ○ 現時点では依存関係に制限は設けていない モノリス (非パッケージ化コード) 認可 パッケージ

Slide 33

Slide 33 text

©2024 Coincheck Inc. 33 やったこと 認可ロジックを集約した認可パッケージの作成を行うことで課題を解決 ● ユーザーが特定の取引を実施できるか否かを返却するクラスを作成し、IFを1つに統一 引数はユーザーIDと取引種別

Slide 34

Slide 34 text

©2024 Coincheck Inc. 34 やったこと 認可ロジックを集約した認可パッケージの作成を行うことで課題を解決 ● ユーザーが特定の取引を実施できるか否かを返却するクラスを作成し、IFを1つに統一 ユーザーの存在チェック

Slide 35

Slide 35 text

©2024 Coincheck Inc. 35 やったこと 認可ロジックを集約した認可パッケージの作成を行うことで課題を解決 ● ユーザーが特定の取引を実施できるか否かを返却するクラスを作成し、IFを1つに統一 取引種別の整合チェック

Slide 36

Slide 36 text

©2024 Coincheck Inc. 36 やったこと 認可ロジックを集約した認可パッケージの作成を行うことで課題を解決 ● ユーザーが特定の取引を実施できるか否かを返却するクラスを作成し、IFを1つに統一 認可ロジックを実行

Slide 37

Slide 37 text

©2024 Coincheck Inc. 37 やったこと 認可ロジックを集約した認可パッケージの作成を行うことで課題を解決 ● ユーザーが特定の取引を実施できるか否かを返却するクラスを作成し、IFを1つに統一 不認可の場合は理由を添えて返却

Slide 38

Slide 38 text

©2024 Coincheck Inc. 38 やったこと 認可ロジックを集約した認可パッケージの作成を行うことで課題を解決 ● ユーザーが特定の取引を実施できるか否かを返却するクラスを作成し、IFを1つに統一

Slide 39

Slide 39 text

©2024 Coincheck Inc. 39 やったこと 認可ロジックを集約した認可パッケージの作成を行うことで課題を解決 ● 認可ロジックは非パブリックなクラスに集約 ○ 非パブリック領域への参照を違反として検知する設定 ○ CIで違反を検知し、違反が残った状態でのマージは不可に設定 packs/authorization/package.yml

Slide 40

Slide 40 text

©2024 Coincheck Inc. 40 3 導入後の評価

Slide 41

Slide 41 text

©2024 Coincheck Inc. 41 packwerkの良い点 packwerkを使ったリファクタでメリットを感じたポイント 既存動作に極力影響を与えない構造

Slide 42

Slide 42 text

©2024 Coincheck Inc. 42 packwerkの良い点 既存動作に極力影響を与えない構造 ● packwerk自体は静的解析なので、本番環境に影響を与えない ● ただし、パッケージ化するにあたってディレクトリ構造を変える必要がある ○ 本来は手動でzeitwerkのオートロードパス追加をする必要があるところ、 packs-railsは起動プロセ スをフックして自動的に追加する 、とREADMEに記載されている Setting up packs-rails is straightforward. Simply by including packs-rails in your Gemfile in all environments, packs-rails will automatically hook into and configure Rails. →ちょっと見えなくて怖い、ので少し深堀り

Slide 43

Slide 43 text

©2024 Coincheck Inc. 43 packs-railsがやっていること packs-railsの中に、Railtieクラスが定義されている ::Rails::Railtieクラスを継承することで packs/rails/railtie.rb

Slide 44

Slide 44 text

©2024 Coincheck Inc. 44 packs-railsがやっていること packs-railsの中に、Railtieクラスが定義されている ::Rails::Railtieクラスを継承することで before_configurationフックの処理を記述できる packs/rails/railtie.rb

Slide 45

Slide 45 text

©2024 Coincheck Inc. 45 packs-railsがやっていること packs-railsの中に、Railtieクラスが定義されている ::Rails::Railtieクラスを継承することで before_configurationフックの処理を記述できる Integrations::Railsのinitiallizeメソッドの中で… packs/rails/railtie.rb

Slide 46

Slide 46 text

©2024 Coincheck Inc. 46 packs-railsがやっていること packs-railsの中に、Railtieクラスが定義されていて、その中で・・・ パッケージ単位で packs/rails/integrations/rails.rb

Slide 47

Slide 47 text

©2024 Coincheck Inc. 47 packs-railsがやっていること packs-railsの中に、Railtieクラスが定義されていて、その中で・・・ パッケージ単位で Rails::Applicationのpathsに追加 packs/rails/integrations/rails.rb

Slide 48

Slide 48 text

©2024 Coincheck Inc. packs/rails/integrations/rails.rb 48 packs-railsがやっていること packs-railsの中に、Railtieクラスが定義されていて、その中で・・・ パッケージ単位で Rails::Applicationのpathsに追加 Packs::Rails.config.pathsの中身は…

Slide 49

Slide 49 text

©2024 Coincheck Inc. このpath個々に対して、パッケージのルートパスを結合して追加をしている 49 packs-railsがやっていること Packs::Rails.config.pathsの中身はこんな感じ packs-rails.rb

Slide 50

Slide 50 text

©2024 Coincheck Inc. このpath個々に対して、パッケージのルートパスを結合して追加をしている 50 packs-railsがやっていること Packs::Rails.config.pathsの中身はこんな感じ 以上の処理がbefore_configuration内で行われるので、後続のzeitwerk によるオートロード対象となり、パッケージ配下のファイルが読み込ま れる packs-rails.rb

Slide 51

Slide 51 text

©2024 Coincheck Inc. 51 packs-railsがやっていること ここに記載されているパス以外はロードされないの? controllersやmodels配下のconcernsディレクトリや、 カスタムディレクトリ(servicesなど)が オートロードパスに追加されなさそうに見える… packs-rails.rb

Slide 52

Slide 52 text

©2024 Coincheck Inc. 52 packs-railsがやっていること ここに記載されているパス以外はロードされないの? controllersやmodels配下のconcernsディレクトリや、 カスタムディレクトリ(servicesなど)が オートロードパスに追加されなさそうに見える… 追加されます! packs-rails.rb

Slide 53

Slide 53 text

©2024 Coincheck Inc. 53 packs-railsがやっていること @app.pathsの中には元々値が入っている 既に属性が定義されているルートに、パッケージのルートパ スを追加で設定するイメージ packs/rails/integrations/rails.rb rails/engine/configuration.rb

Slide 54

Slide 54 text

©2024 Coincheck Inc. rails/engine/configuration.rb 54 packs-railsがやっていること @app.pathsの中には元々値が入っている packs-railsで注入した各パッケージのパスと、globオプションをもとに、下記のようなカスタム ディレクトリやconcernsディレクトリがzeitwerkのオートロードパスに設定される - packs/authorization/models/concerns - packs/authorization/services

Slide 55

Slide 55 text

©2024 Coincheck Inc. 55 packs-railsがやっていること Railsエンジンとして追加も可能 packs/rails/integrations/rails.rb

Slide 56

Slide 56 text

©2024 Coincheck Inc. 56 packwerkの良い点(あらためて) ● 構造 ○ packwerk自体は静的解析なので、本番環境に影響を与えない ○ packs-railsを併用することで、ディレクトリ構造を変更するだけでモジュラーモノリス構造、パッケージ 化を安全・低コスト に試すことができる ● 機能 ○ パブリック領域の設定 ができる ○ 依存関係を制限できる(現状では有用な役割とはなっていない)

Slide 57

Slide 57 text

©2024 Coincheck Inc. 57 packwerkで防ぎきれない観点🫠

Slide 58

Slide 58 text

©2024 Coincheck Inc. 58 packwerkで防ぎきれない観点 モノリス側で再び同じようなロジックが作成されることを機械的に防ぐことはできない

Slide 59

Slide 59 text

©2024 Coincheck Inc. 59 packwerkで防ぎきれない観点、とその対策 モノリス側で再び同じようなロジックが作成されることを機械的に防ぐことはできない ● まずは全体認知が必要 ○ 各チームへの説明 ○ README.mdの整備

Slide 60

Slide 60 text

©2024 Coincheck Inc. 60 packwerkで防ぎきれない観点、とその対策 モノリス側で再び同じようなロジックが作成されることを機械的に防ぐことはできない ● まずは全体認知が必要 ○ 各チームへの説明 ○ README.mdの整備 ● 機械的に検知もしたい ○ 今回のケースは、パッケージ内で判定しているステータスの参照をカスタム copを用いて検知 ○ カスタムcop検知を監視するため、リリース時点での rubocop指摘をBigQueryに蓄積し、 LookerStudioで監視する仕組みも整備

Slide 61

Slide 61 text

©2024 Coincheck Inc. 61 今後の展望🗻

Slide 62

Slide 62 text

©2024 Coincheck Inc. 62 今後の展望 現在社内で進めていること ● 機能のパッケージ化をいくつか並行で進めている 今後は ● 目先は機能のパッケージ化を進めていく ● 機能のパッケージ化の先に、ドメイン分割など次の一手の兆しが見えれば・・・ モノリス (非パッケージ化コード) 認可パッケージ XXXパッケージ XXXパッケージ

Slide 63

Slide 63 text

©2024 Coincheck Inc. 63 4 まとめ

Slide 64

Slide 64 text

©2024 Coincheck Inc. 64 まとめ packwerkを利用した認可ロジックの集約で・・・ ● 取引可否の判定をするならココ、という目印ができた👍 ● サービス全体で仕様を横串で確認することが容易になった👍 ● ドメインロジックの複雑度が下がった👍 ● 新しいプロダクトでも認可ロジックの適用がしやすくなった👍 ○ 実績もあり ● 既存プロダクトの仕様変更もしやすくなった👍 ○ 実績もあり ● 巨大なコードベースに対する安全なリファクタリングツールとしてのpackwerkのメ リットが見えた👍

Slide 65

Slide 65 text

©2024 Coincheck Inc. 65 ご清聴ありがとうございました󰢛

Slide 66

Slide 66 text

新しい価値交換を、もっと身近に