Laravel DDD application structures
This post will give a quick overview of different possible application setups to start with Domain Driven Design (DDD). If you want to learn more about DDD I would recommend the books and articles by Vaughn Vernon or Matthias Noback.
There are different ways to set up your application when you want to structure it by domain and separate the layers in your application.
In the following overviews I will only show the source's directories to keep it simple.
The different methods will increase in the amount of setup that is necessary to get started.
They (probably) don't all adhere to DDD in its purest form, but that was never the goal for me.
I tried them all but I do not have a clear favorite; an important factor in my consideration would be the experience of the team and what they would feel comfortable with to use.
1. The Subfolder
The first structure has a low barrier to entry, it involves creating a
Domain folder inside
This does not seem like much, but it could come with additional guidelines your team might agree on,
such as "all domain code should be covered by unit tests, all other code will use Laravel's feature tests."
Pro: suits well for a first attempt at DDD. Con: the domain might get muddy and 'disappear' within the application.
app/ Console Domain Exceptions Http Models Providers bootstrap config database lang public resources routes storage tests
2. The Other Folder
The next method places the domain outside the app folder, this requires a minimal setup in your
composer.json to define the new namespace besides
Of course the same thing applies to this method (and in fact, to all methods); your team may make additional guidelines and document them in the readme.
Pro: this is getting one step closer to the screaming architecture because a new developer will immediately spot the domain of the application.
Con: you might experience some 'friction' as to where to find certain classes (do I open
app bootstrap config domain database lang public resources routes storage tests
3. The Package
This will likely use a package (shameless plug) to manage your domain as a package (sometimes also called a module).
Pro: useful approach to (strictly) separate domains from your application, and their development as well. Con: there will be extra overhead in registering, installing and controlling the packages.
app bootstrap config database lang packages/ DomainA DomainB public resources routes storage tests
4. The Hexagon
This is when you want to go the extra mile and decouple your application, infrastructure and domain code. What I like about this approach is having the three layers separated, but still together and not in between the config, public and other folders.
Pro: it clearly 'screams' what your application is, does and has. Your domain code is decoupled from framework implementation and every layer can be fully tested with its own strategy (unit, feature, end-to-end, etc.). Con: A couple of hours extra setup, and less likely to be able to automatically be upgraded (because tools like Shift and Rector might not recognise what they need for their tools).
app/ Application/ Events Jobs Listeners Domain/ DomainA DomainB Infrastructure/ Console Exceptions Http Models Providers bootstrap config domain database lang public resources routes storage tests
In conclusion, it is possible to follow principles of Domain Driven Design as much with Laravel as it is with any other framework. Make sure to dive into the concepts and ideas behind it and let it spark your (and your teams) creativity!