Chapter

Putting it together in Laravel

Everything so far, applied to a real Laravel 11 app: organize code by domain, map DDD onto Eloquent and the container, keep the domain framework-free, build one module end to end, and know when the defaults are already enough.

Software Architecture 5 Lessons from courses

About this chapter

Seven chapters gave you the ideas: boundaries, Domain-Driven Design, hexagonal ports and adapters, the application layer, event-driven design. This chapter grounds all of it in the framework you actually ship with. You'll reorganize a Laravel app by domain instead of by file type, map the DDD building blocks onto Laravel's own tools (Eloquent as an adapter, the service container as the wiring, jobs and events for domain events), and see why keeping the domain as plain PHP pays off - and what it costs. Then we build one module, Billing, from the aggregate down to the controller, so the pieces click together. The last lesson is the counterweight: for many apps, Laravel's defaults are the right answer, and this chapter is as much about when not to reach for this as when to.

Lessons from courses

  1. 1 Structure a Laravel app by domain Structure a Laravel 11 project by domain (app/Billing, app/Catalog) instead of by type. A folder layout, the PSR-4 autoload note, and the coupling trap to avoid.
  2. 2 Mapping DDD onto Laravel Mapping DDD onto Laravel 11: Eloquent as a persistence adapter behind a repository, the service container as wiring, and jobs and events for domain events.
  3. 3 Keeping the domain framework-free Build a framework-free domain layer in Laravel: entities, value objects and use cases as plain PHP with no Illuminate imports. Why it pays off - and what it costs.
  4. 4 A worked module end to end A worked Laravel module end to end: an Invoice aggregate, a Money value object, the repository pattern as a port with an Eloquent adapter, a use-case handler, and a controller.
  5. 5 When Laravel's defaults are enough When to use DDD in Laravel and when Laravel's defaults win: for CRUD apps and small teams, fat models and controllers are fine. DDD earns its keep with real complexity.
Software Architecture Go to course