DevPath · Learn to code ESPTEN

Data, ORMs and layered architecture

Beyond the monolith: microservices and events

The monolith

Everything you have built so far lives in a single application: one process that is compiled, tested and deployed as a block. That is a monolith. The layers (controller → service → repository) are inside the same deployment and call each other with simple function calls.

The monolith has great virtues: it is simple to develop, debug and deploy, and an internal call is instant. For most projects it is the right choice. Its limits appear when the team and the code grow a lot: everything deploys together (a small change forces redeploying everything) and you cannot scale only the part that needs it.

Microservices

The alternative is microservices: instead of one big application, many small, independent services, each responsible for a part of the domain (users, payments, catalog...). Each service:

This way, the payments team deploys whenever it wants without touching the catalog team, and you can scale only the saturated service. The price is heavy operational complexity: the network can fail, you must coordinate deployments, observe many services and live without transactions spanning several of them.

Event-driven architecture

Coupling services with direct HTTP calls creates rigid dependencies: if A calls B, A needs to know that B exists and wait for it to respond. Event-driven architecture flips it around: instead of calling, a service publishes an event ("OrderCreated") on an event bus, and other services subscribe to the events that interest them. It is the publish/subscribe pattern (pub/sub).

Orders ──(publishes "OrderCreated")──▶ Event bus
                                         ├──▶ Billing (subscribed)
                                         └──▶ Email (subscribed)

The publisher does not know who is listening: to add a new reaction (notify logistics) you just subscribe another service, without touching Orders. In exchange you give up immediate consistency: subscribers react a bit later, so the system lives in eventual consistency (everything ends up consistent, but not at the same instant).

Sagas at a high level. When an operation spans several services (reserve stock, charge, ship) there is no global transaction. It is modeled as a saga: a sequence of steps where, if one fails, compensation actions run to undo the previous ones. In the choreography variant, there is no central coordinator: each service reacts to the others' events and publishes its own.

When to make the jump?

Advantages Drawbacks
Monolith Simple, fast to develop and deploy Deploys and scales as a block
Microservices Independent scaling and deployment, team autonomy Operational complexity, network, eventual consistency

It is not a choice of "better or worse", but of trade-off. Most systems start as a well-structured layered monolith and only extract microservices when the pain of joint deployment and scaling justifies it.

Put this into practice

DevPath is a hands-on course: you read the theory here; in the app you put it into practice with exercises that really run, offline.

Start free in the app →
← Layered architectureView the module →