Building a Modular Monolith Architecture

Jul 1, 2024

Building a Modular Monolith Architecture

Introduction

  • Modular Monolith: A software design approach where a monolithic application is divided into interchangeable modules.
  • Key Concept: Modules - logical partitions within a single deployment unit rather than separate services.
  • Importance: Emphasizes logical separation without physical distribution, enabling maintainable and scalable design.

Example: eShop Application

  • System Comparison:
    • Monolithic System: Single deployment unit, one database (e.g., PostSQL).
    • Microservices System: Multiple physically separated services (e.g., catalog, order, customer, and collaboration).
    • Modular Monolith: Logical separation into modules but within a single application and database.
  • Challenges:
    1. Defining modules or bounded contexts correctly.
    2. Solving communication between modules.
    3. Ensuring data independence between modules.

Solution Structure: Trainer Sphere Application

  • Modules: Users, Training, Notifications.
  • Clean Architecture: Domain, Application, Infrastructure, Persistence, Endpoints.
  • Single Executable: Single web API application with logical separation into modules.

Detailed Breakdown: Users Module

  • Domain Layer: Handles entities, domain events, and contracts.
    • Example: User entity, roles and permissions, domain events.
  • Application Layer: Implements use cases using Railway Oriented Programming (ROP).
    • Example: RegisterUser use case, handling domain events, persisting to database.
  • Integration Events: Facilitates communication between modules.
    • Example: User Registered event, converting domain events to integration events.

Communication Between Modules

  • Event Bus: Using Mass Transit for in-memory transport.
  • Integration Event Handlers: Classes that handle events published by other modules.
    • Example: Invitation Sent handler, Invitation Canceled handler.

Persistence and Database Structure

  • Distinct Schemas: Separate schemas for each module to ensure independence.
    • Example: Users schema, roles, permissions.
  • Patterns: Reliable messaging using inbox and outbox tables.
  • Entity Relationships: Detailed ER diagrams for each module.

Dependency Injection and Infrastructure

  • IModuleInstaller Interface: Registers services and dependencies for each module.
  • Assembly Scanning: Automatically detect and register modules.
  • Service Installers: Specific classes for setting up services like MediatR, pipeline behaviors.

Endpoints and Authorization

  • API Endpoints: Defined using ESAPI Endpoints library, attributes for Swagger and authorization.
    • Example: RegisterUser endpoint, UpdateUser endpoint, GetUser endpoint.
  • Custom Attributes: Enforces specific authorization policies and permissions.

Web API Integration

  • Service Installation: Integrates module services and controllers in the web API.
  • Configuration: Setting up Swagger, logging, authentication, and running the application.

Summary

  • Bounded Contexts: Represent domain concepts in different ways across modules.
    • Example: User in Users module, Trainer in Training module.
  • High-Level Insights: Introduction to modular monolith architecture with plans for more content.