Skip to content

labg94/modularms

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ModularMS – Profile‑Driven Modular Deployment Architecture

Overview

ModularMS demonstrates an architectural approach where modules are the primary design unit, and deployment topology is a runtime decision controlled via profiles.

The same codebase can be deployed as:

  1. A modular monolith
  2. One microservice per module
  3. Grouped microservices, where multiple modules are deployed together

This allows teams to adapt architecture to team size, domain maturity, and operational capacity without rewriting business logic.

The goal is not to avoid microservices — it is to delay irreversible architectural decisions while preserving clean boundaries.


Core Principles

  • Modules first, services second
  • Deployment is configuration, not refactoring
  • Boundaries are enforced in code, not infrastructure
  • DX and productivity are first‑class concerns

Architecture Model

Logical Architecture (Always the Same)

┌─────────────┐   ┌─────────────┐   ┌─────────────┐
│  Module A   │   │  Module B   │   │  Module C   │
│ (Domain)    │   │ (Domain)    │   │ (Domain)    │
└─────┬───────┘   └─────┬───────┘   └─────┬───────┘
      │                 │                 │
      └────── Module APIs / Interfaces ───┘

Modules:

  • Own their domain logic
  • Expose explicit APIs
  • Do not depend on deployment topology

Deployment Topologies

1. Modular Monolith

Description All modules enabled in a single application.

┌──────────────────────────────────────┐
│              Application             │
│ ┌────────┐ ┌────────┐ ┌────────┐   │
│ │Module A│ │Module B│ │Module C│   │
│ └────────┘ └────────┘ └────────┘   │
└──────────────────────────────────────┘

When to use

  • Small teams (1–3 devs)
  • Early product stage
  • High iteration speed required

Benefits

  • Fastest local development
  • Simplest debugging
  • Zero network overhead
  • Minimal DevOps

2. One Microservice per Module

Description Each module deployed independently using profiles.

┌────────────┐   ┌────────────┐   ┌────────────┐
│ Module A   │   │ Module B   │   │ Module C   │
│ Service    │   │ Service    │   │ Service    │
└────────────┘   └────────────┘   └────────────┘

When to use

  • Growing teams
  • Independent scaling needed
  • Clear service ownership

Benefits

  • Fault isolation
  • Independent deployment
  • Module‑level scaling

3. Grouped Microservices (Key Differentiator)

Description Multiple related modules deployed together as a single service.

┌──────────────────┐   ┌──────────────────┐
│  Service X       │   │  Service Y       │
│ ┌────────────┐  │   │ ┌────────────┐  │
│ │ Module A   │  │   │ │ Module C   │  │
│ │ Module B   │  │   │ │ Module D   │  │
│ └────────────┘  │   │ └────────────┘  │
└──────────────────┘   └──────────────────┘

When to use

  • Medium teams
  • Closely related domains
  • Microservices feel too granular

Benefits

  • Fewer services to operate
  • Reduced network chatter
  • Better performance
  • Still maintains modularity

Why This Improves Developer Experience

  • One mental model across all environments
  • No architectural rewrite when scaling
  • Fast onboarding
  • Easier debugging
  • Fewer repositories and pipelines

Developers always work with the same modules, regardless of deployment mode.


Why This Improves Team Productivity

  • Architecture scales with team size
  • Cross‑module changes remain simple
  • Operational complexity is incremental
  • Teams avoid premature DevOps burden

Module Design Rules (Critical)

To keep this architecture healthy:

1. Modules Own Their Domain

  • Each module has a single responsibility
  • No shared domain models across modules

2. Explicit Module APIs

  • All cross‑module access goes through interfaces
  • No direct access to internals

3. No Conditional Logic in Business Code

  • Profiles decide what starts, not how logic behaves

4. Infrastructure at the Edge

  • HTTP, messaging, persistence adapters live at module boundaries

5. Enforce Dependency Direction

  • No cyclic dependencies
  • Shared utilities must be minimal and stable

Profile Strategy

Profiles control:

  • Which modules start
  • Which adapters are active (local vs remote)

Example strategies:

  • monolith
  • module-a
  • module-a,module-b

Profiles must be:

  • Explicit
  • Documented
  • Validated at startup

Testing Strategy

  • Module tests: always run
  • Monolith mode tests: fast feedback
  • Service mode tests: critical paths only

Avoid testing all permutations blindly — focus on real deployment modes.


When to Split a Module into Its Own Service

Use these signals:

✔ Independent scaling pressure ✔ Different uptime requirements ✔ Team ownership boundaries ✔ Heavy write or compute load ✔ External integration complexity

Avoid splitting just because "microservices are better".


Trade‑Offs & Limitations

  • Profile complexity
  • Risk of hidden coupling
  • Larger testing matrix
  • Requires architectural discipline

This architecture optimizes for small and growing teams, not hyperscale organizations.


Summary

ModularMS shows how teams can:

  • Start simple
  • Scale responsibly
  • Preserve DX
  • Avoid premature distributed complexity

Architecture should grow with the team — not ahead of it.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages