diff options
Diffstat (limited to 'doc/architecture/blueprints/modular_monolith/bounded_contexts.md')
-rw-r--r-- | doc/architecture/blueprints/modular_monolith/bounded_contexts.md | 27 |
1 files changed, 9 insertions, 18 deletions
diff --git a/doc/architecture/blueprints/modular_monolith/bounded_contexts.md b/doc/architecture/blueprints/modular_monolith/bounded_contexts.md index 0f71e24864e..8133106050d 100644 --- a/doc/architecture/blueprints/modular_monolith/bounded_contexts.md +++ b/doc/architecture/blueprints/modular_monolith/bounded_contexts.md @@ -41,11 +41,16 @@ The majority of the code is not properly namespaced and organized: In June 2023 we've started extracing gems out of the main codebase, into [`gems/` directory inside the monorepo](https://gitlab.com/gitlab-org/gitlab/-/blob/4c6e120069abe751d3128c05ade45ea749a033df/doc/development/gems.md). -This is our first step towards modularization: externalize code that can be -extracted to prevent coupling from being introduced into modules that have been -designed as separate components. +This is our first step towards modularization. -These gems as still part of the monorepo. +- We want to separate generic code from domain code (that powers the business logic). +- We want to cleanup `lib/` directory from generic code. +- We want to isolate code that could live in a separate project, to prevent it from depending on domain code. + +These gems as still part of the monorepo but could be extracted into dedicated repositories if needed. + +Extraction of gems is non blocking to modularization but the less generic code exists in `lib/` the +easier will be identifying and separating bounded context. ### 1. What makes a bounded context? @@ -103,17 +108,3 @@ With this static list we could: - Understand where to place new classes and modules. - Enforce if any top-level namespaces are used that are not in the list of bounded contexts. - Autoload non-standard Rails directories based on the given list. - -## Glossary - -- `modules` are Ruby modules and can be used to nest code hierarchically. -- `namespaces` are unique hierarchies of Ruby constants. For example, `Ci::` but also `Ci::JobArtifacts::` or `Ci::Pipeline::Chain::`. -- `packages` are Packwerk packages to group together related functionalities. These packages can be big or small depending on the design and architecture. Inside a package all constants (classes and modules) have the same namespace. For example: - - In a package `ci`, all the classes would be nested under `Ci::` namespace. There can be also nested namespaces like `Ci::PipelineProcessing::`. - - In a package `ci-pipeline_creation` all classes are nested under `Ci::PipelineCreation`, like `Ci::PipelineCreation::Chain::Command`. - - In a package `ci` a class named `MergeRequests::UpdateHeadPipelineService` would not be allowed because it would not match the package's namespace. - - This can be enforced easily with [Packwerk's based Rubocop Cops](https://github.com/rubyatscale/rubocop-packs/blob/main/lib/rubocop/cop/packs/root_namespace_is_pack_name.rb). -- `bounded context` is a top-level Packwerk package that represents a macro aspect of the domain. For example: `Ci::`, `MergeRequests::`, `Packages::`, etc. - - A bounded context is represented by a single Ruby module/namespace. For example, `Ci::` and not `Ci::JobArtifacts::`. - - A bounded context can be made of 1 or multiple Packwerk packages. Nested packages would be recommended if the domain is quite complex and we want to enforce privacy among all the implementation details. For example: `Ci::PipelineProcessing::` and `Ci::PipelineCreation::` could be separate packages of the same bounded context and expose their public API while keeping implementation details private. - - A new bounded context like `RemoteDevelopment::` can be represented a single package while large and complex bounded contexts like `Ci::` would need to be organized into smaller/nested packages. |