バックエンド分解 ADR 004: 横断的ライブラリを gem に抽出する
コンテキスト
ADR-001 は、今日では主に lib/ と ee/lib に存在する技術的で横断的なコードである「プラットフォーム」層を、gem として抽出された独立したライブラリへ分解できることを確立しました。この ADR は、その進め方を確約するものです。
lib/gitlab/ は、3 種類のコードが混在する「何でも入れ」になっています。本当に汎用的なユーティリティ、GitLab 固有だが分離されたライブラリ、そして ActiveRecord モデルと Rails ランタイムに密結合したコードです。最後のカテゴリはプラットフォームコードではなく、ドメインコードです。
詳細な抽出パターン、候補の階層、順序付けのガイダンスは、単一の情報源である 横断的ライブラリを gem に抽出するページにあります。
決定事項
横断的な プラットフォーム ライブラリを lib//ee/lib から、Gemfile で path: によって参照される gems/ 配下の Ruby gem へ抽出します。これには次のコミットメントが伴います:
- ライブラリは ActiveRecord 非依存でなければなりません。 真の横断的関心事(ロギング、エラーレポート、メトリクス、レートリミッター、パーサー、
Banzaiのような汎用ユーティリティ)だけが gem になります。「ライブラリ」に AR データを注入する必要がある場合、それは汎用的ではないというシグナルです。 - ドメインコードはバウンデッドコンテキスト戦略に従います。
lib/gitlab/から取り出された AR 結合コードは、config/bounded_contexts.ymlに従って バウンデッドコンテキストの名前空間へ移動し、Gitlab::プレフィックスを保持しません。プラットフォームコードはGitlab::を保持できます。 - Gem 抽出はアトミックなリファクタリング であり、段階的にしか分離できないコードについては任意で Packwerk の支援を受けます。Packwerk は補完的なツールであり、主要な経路ではありません。
- 細かく、下から始めます。 依存関係のない最下層のコードから始め、小さく焦点を絞った gem を 1 つずつ抽出します。これにより、抽出パターンと CI の配線をより早く実証できます。
結果
- 暗黙的だった依存関係が、gem 境界で明示的かつ強制されるようになります。隠れた結合はエラーとして表面化します。
- 各 gem は明示的な
feature_category:とより明確な担当者を持ち、独自の分離された CI スイートを実行します。 - CI の高速化は実際には控えめです。
lib/gitlab/のライブラリは安定しており、gem 同士の相互接続も残るため、主な価値は CI 時間の削減ではなく、パターン、ツール、分離の確立にあります。 - この取り組みは有用な分類を強制します。AR 非依存の抽出に抵抗するコードはドメインコードとして明らかになり、そのバウンデッドコンテキストへ振り分けられます。
代替案
- プラットフォームコードを
lib/に残し、境界の強制を静的解析だけに頼る。主要な経路としては却下します。すべてをlib/に置いたままでは設計は改善しません。インターフェイスは曖昧なままで、結合は制約されません。また、コードはモノリスのスイートの一部であり続けるため、実行する CI テストを減らすこともできません。gem は、lib/では提供できない明示的で分離された依存関係宣言と独自の CI スイートをコードに与えます。
最終更新 July 30, 2026: Merge pull request #483 from kyama0/translation/batch-2026-07-29-1 (
c955a93f)