DDD in Laravel on a Real Project

A practical series about Domain-Driven Design in Laravel: domain boundaries, aggregates, business rules, services, transactions, events, and read models from a real project.

DDD in Laravel on a Real Project
ddd-in-practice-when-crud-stops-being-enough-cover.png
Laravel

DDD in Practice: When CRUD Stops Being Enough

CRUD works well while an entity is truly simple. Once states, allowed transitions, dependencies, and rules appear, a controller starts knowing too much. Simple examples show when a domain model becomes more useful than a collection of create, update, and delete operations.

99
how-i-find-domain-boundaries-while-the-system-is-still-growing-cover.png
Laravel

How I Find Domain Boundaries While the System Is Still Growing

Domain boundaries are rarely obvious at the beginning. In practice, I look at language, rules, reasons for change, and lifecycle. If two parts of the system change for different reasons, that is a strong signal that they may not belong in the same context.

107
where-should-a-business-rule-live-controller-service-or-domain-model-cover.png
Laravel

Where Should a Business Rule Live: Controller, Service, or Domain Model?

A business rule is easy to leave in a controller or application service at first. Once several use cases depend on it, the rule often reveals itself as a domain invariant. This article shows how I separate request validation, use-case coordination, and domain rules.

91
application-service-vs-domain-service-how-i-separate-their-responsibilities-cover.png
Laravel

Application Service vs Domain Service: How I Separate Their Responsibilities

For a long time it was easy for me to call any non-trivial logic a service. In practice, one distinction helped: an application service coordinates the use case, transaction, repository, and external dependencies, while a domain service expresses a domain rule that does not naturally belong to one object.

127
ddd-in-practice-avn-center-boundaries-aggregate-roots-consistency-cover.png
Laravel

DDD in Practice in AVN Center: Boundaries, Aggregate Roots, and Consistency

Using ProductRegistry, I show several practical DDD decisions: how Domain, Application, Infrastructure, and Delivery are separated, why ProductRegistration and BootstrapInvitation have their own boundaries, where events fit, and where one strong-consistency transaction is the better model.

128
domain-event-or-direct-method-call-how-i-choose-between-them-cover.png
Laravel

Domain Event or Direct Method Call: How I Choose Between Them

I do not use domain events everywhere. If the second action is required to protect an invariant, I keep it as a direct call in one transaction. If another part of the system only reacts to an already committed fact, a domain event is often a better fit.

80
ddd-read-models-why-reads-do-not-always-need-the-domain-model-cover.png
Laravel

DDD Read Models: Why Reads Do Not Always Need the Domain Model

The domain model primarily protects rules when state changes. A list, table, or API response often needs a different data shape. This article explains why a separate read model does not violate DDD and often makes the code simpler.

95
what-i-would-do-differently-if-i-started-a-ddd-project-again-cover.png
Laravel

What I Would Do Differently If I Started a DDD Project Again

If I started a DDD project again, I would spend less time trying to design everything up front. I would identify invariants earlier, introduce abstractions more carefully, separate reads sooner, and let database tables influence the domain model less.

71