Skip to content

ADR 2: Use Modular Monolith System Architecture

Status

Accepted

Context

Usage of bounded contexts as we model the application is strongly desired. To reduce the overhead and orchestration of each context, a single deployment unit pattern is desired.

The modular monolith architecture separates bounded contexts into modules with isolation rules such as:

  • A single db, but modules are separated by schema and cross-querying is not allowed.
  • Direct project references are not allowed except for integration event/contract assemblies
  • Communication between modules happens through the API/event bus only.

A single pipeline and deployable unit also:

  • Reduces the overhead of adding new modules.
  • Eases test automation by requiring a good state of all modules at all times.

References: youtube youtube

Decision

The benefit of fully isolated services does not align with the scope and team size. The modular monolith allows us to add complexity as needed.

Mono services

The majority of contexts will reside in a modular monolith.

Standalone services

To alleviate concerns of requiring a simultaneous deployment of the network rail contexts, will be structure as standalone services with separate pipelines. These services are still under the umbrella of BoyarServices and participate in integration events.

Consequences

What becomes easier or more difficult to do because of this change? The contexts residing in the modular monolith will benefit as mentioned with exceptions made for the standalone services: - As we wish to include both the 'mono' service and standalone services within the same umbrella, an in-memory event bus will need to substituted for a standalone implementation. - Integration events will require more complexity to allow for independent deployments of the sandalone services. Masstransit versioning is considered. - Common cross-cutting code is still desired and will require the added complexity of NuGet to allow for independent deployments.