Loslegen
Javaneer
Zurück zur Stufe
Stufe 4·Der modulare Monolith

Die Startrampe zu Microservices

Ein gut modularisierter Monolith ist der beste Ausgangspunkt: behalte die Module, bis Skalierung, Team oder Deployment das Herauslösen eines Dienstes rechtfertigen - dann ist die Naht bereits da.

13 Min. LesezeitFortgeschritten

Deutsche Übersetzung in Arbeit

Diese Lektion ist noch nicht ins Deutsche übersetzt und wird daher auf Englisch angezeigt. Der Rest der Seite ist vollständig lokalisiert.

Auf dieser Seite

This module's closing argument ties it back to where it began. A well-modularized monolith isn't a consolation prize you settle for until you can afford "real" microservices - it's the best possible starting point, and often the best permanent home. And when a genuine need to extract a service does arrive, the modular monolith is what makes that extraction tractable instead of terrifying. Modularity first, distribution later - only if justified.

The monolith-first strategy

The strategy, argued by many senior engineers (famously "MonolithFirst" by Martin Fowler), goes:

  1. Start with a modular monolith. One deployable, clean feature modules, enforced boundaries, event-based communication. You get most of the design benefits of microservices with none of the distributed cost.
  2. Get the boundaries right where they're cheap to move. In a monolith, refining a module boundary is refactoring - move a class, adjust an API. You will get boundaries wrong at first; the monolith lets you fix them freely as the domain clarifies.
  3. Extract a module into a service only under real pressure - never speculatively.

The whole point: defer the hardest, most expensive, least reversible decision (a network boundary) until you have the knowledge to make it well - which you only gain by building the thing.

What actually justifies extraction

Extract a module into its own service when a concrete, present force demands it - not because microservices are fashionable:

  • Independent scaling. One module (fraud scoring, image processing) has wildly different load or resource needs (GPU, memory) than the rest, and scaling the whole monolith for it is wasteful.
  • Independent deployment / team autonomy. A separate team needs to release a module on its own cadence without coordinating with everyone else's deploys. (This is Conway's Law: at scale, service boundaries mirror team boundaries.)
  • Different technology. A module is genuinely better in another language or runtime.
  • Fault isolation. A module must fail without taking the rest down, beyond what in-process isolation gives.

If none of these apply, the module is better off staying in the monolith - simpler to develop, test, and operate. "We might need to scale someday" is not a justification; it's speculation, and you can extract when someday arrives.

Why the modular monolith makes extraction easy

Here's the payoff for all the discipline. When you do extract a module, a modular monolith has already done the hard parts:

  • The boundary exists. The module has a public API and a known set of published/consumed events - that API becomes the service's network interface, and those events become messages. You're not discovering the boundary under fire; you're promoting one that's already clean.
  • The data is owned. Because each module already owns its tables and no one queries across boundaries (the cardinal rule), the module's data can move with it - the single hardest part of extraction is already done.
  • Communication is the right shape. In-process API calls become REST/gRPC; in-process events become a message broker. The pattern doesn't change, only the transport.

Contrast this with extracting a service from a ball of mud: you first have to find the boundary, untangle shared data, and unpick a web of direct calls - which is why big-bang monolith-to-microservices rewrites so often fail. The modular monolith turns a terrifying rewrite into a mechanical promotion.

Don't extract to escape a mess - fix the mess first

A common, doomed move: 'our monolith is a tangled mess, so let's break it into microservices to force boundaries.' You can't extract clean services from unclear boundaries - you'll get a distributed monolith, now with network calls in the tangle. Do the modularization inside the monolith first (where it's cheap and safe); only extract once the module is genuinely clean and a real pressure justifies the network. Microservices amplify whatever structure you already have - impose the structure before you distribute.

Building with rooms before adding separate buildings

A modular monolith is a well-designed house with clearly walled rooms, each with its own door and utilities. If one room - say a home business - grows enough to need its own entrance, parking, and hours, you can convert it into a separate annex relatively cleanly, because it was already a self-contained room with its own plumbing and a door to the outside. Trying instead to carve a separate building out of a single open-plan space with no internal walls means first figuring out where walls should go while people are living there - far harder and riskier. Build the rooms first; add the separate building only when a room truly needs to be its own address, and the conversion is a renovation, not a demolition.

Decide whether to extract

A company's modular monolith has a well-bounded notifications module (its own API, its own events, its own tables). Two proposals arrive: (a) extract it to a service because 'microservices are best practice'; (b) extract it because the notifications volume has grown 50x, it needs to scale independently on separate hardware, and a newly-formed messaging team wants to own its release cadence. Evaluate both, and explain why the extraction would be relatively smooth here.

Why is a well-modularized monolith the ideal starting point even if you might want microservices later?

Key takeaways

  • A well-modularized monolith is the best starting point (and often permanent home) - most of microservices' design benefits without the distributed cost.
  • Monolith-first defers the hardest, least reversible decision (a network boundary) until you've learned the domain by building it; boundaries are cheap to move in a monolith.
  • Extract a module into a service only under concrete pressure: independent scaling, team autonomy/deployment (Conway's Law), different tech, or fault isolation - never speculatively.
  • A modular monolith makes extraction tractable: the module's public API becomes the network interface, its events become messages, and its owned data moves with it.
  • Never extract to escape a mess - you can't carve clean services from unclear boundaries; modularize inside the monolith first, then distribute only when justified.
War diese Lektion hilfreich?
Diese Seite auf GitHub bearbeiten