1--- 2stage: none 3group: unassigned 4info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments 5--- 6 7# Backend directory structure 8 9## Use namespaces to define bounded contexts 10 11A healthy application is divided into macro and sub components that represent the contexts at play, 12whether they are related to business domain or infrastructure code. 13 14As GitLab code has so many features and components it's hard to see what contexts are involved. 15We should expect any class to be defined inside a module/namespace that represents the contexts where it operates. 16 17When we namespace classes inside their domain: 18 19- Similar terminology becomes unambiguous as the domain clarifies the meaning: 20 For example, `MergeRequests::Diff` and `Notes::Diff`. 21- Top-level namespaces could be associated to one or more groups identified as domain experts. 22- We can better identify the interactions and coupling between components. 23 For example, several classes inside `MergeRequests::` domain interact more with `Ci::` 24 domain and less with `ImportExport::`. 25 26```ruby 27# bad 28class MyClass 29end 30 31# good 32module MyDomain 33 class MyClass 34 end 35end 36``` 37 38### About namespace naming 39 40A good guideline for naming a top-level namespace (bounded context) is to use the related 41feature category. For example, `Continuous Integration` feature category maps to `Ci::` namespace. 42 43Alternatively a new class could be added to `Projects::` or `Groups::` if it's either: 44 45- Strictly related to one of these domains. For example `Projects::Alias`. 46- A new component that does not have yet a more specific domain. In this case, when 47 a more explicit domain does emerge we would need to move the class to a more specific 48 namespace. 49 50Do not use the [stage or group name](https://about.gitlab.com/handbook/product/categories/#devops-stages) 51since a feature category could be reassigned to a different group in the future. 52 53```ruby 54# bad 55module Create 56 class Commit 57 end 58end 59 60# good 61module Repositories 62 class Commit 63 end 64end 65``` 66 67On the other hand, a feature category may sometimes be too granular. Features tend to be 68treated differently according to Product and Marketing, while they may share a lot of 69domain models and behavior under the hood. In this case, having too many bounded contexts 70could make them shallow and more coupled with other contexts. 71 72Bounded contexts (or top-level namespaces) can be seen as macro-components in the overall app. 73Good bounded contexts should be [deep](https://medium.com/@nakabonne/depth-of-module-f62dac3c2fdb) 74so consider having nested namespaces to further break down complex parts of the domain. 75For example, `Ci::Config::`. 76 77For example, instead of having separate and granular bounded contexts like: `ContainerScanning::`, 78`ContainerHostSecurity::`, `ContainerNetworkSecurity::`, we could have: 79 80```ruby 81module ContainerSecurity 82 module HostSecurity 83 end 84 85 module NetworkSecurity 86 end 87 88 module Scanning 89 end 90end 91``` 92 93If classes that are defined into a namespace have a lot in common with classes in other namespaces, 94chances are that these two namespaces are part of the same bounded context. 95