Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

NoorDeen's avatar

Folder and namespace structure with DDD

what is the best way to organize my application structure when Develop using Domain Driven Design and Laravel 4 or 5 ?

0 likes
51 replies
nrivero's avatar

I don't know if its the best but the way I do it is. AppName\Solution\Layer... For instance, if I have a repository for a budgeting app I would do something like this..

Budget\Core\Infrastructure\Data\UserRepositoryInterface

the reason I add a "solution" to the namespace is in case I want to add different functionality or section to my web app. Like if my app is a e-commerce store but I wanted to add blogging functionality.

I add the "layer" to the namespace so I can quickly keep track of what layers of my application are being interacted on by the current class. I usually have a "User Interface", "Application", "Domain" and "Infrastructure" layer.

I'm curious how other people approach it.

1 like
jekinney's avatar

I prefer to keep my namspaces short. I'll use different main folders as for each main area similar to nrivieo but not as deep. My namespaces generally don't go over 3 words, 4 at the most.

4 likes
thepsion5's avatar
Level 25

I usually divide large apps into 4-5 namespaces, all starting with an app-wide namespace. For this example, I'm going to create a ToDo List app, so the base namespace will be ToDo.

Then I have 3 namespaces grouped under that one:

  • App - Laravel specific functionality - validator classes, service providers base models, etc

  • Domain - All of my business logic, such as entities, repository interfaces, and domain services

  • Infrastructure - All of the persistence logic. That includes repository implementations, cache decorators, etc

And in addition to those, I have at least one "port" namespace. For a typical web app it would be Http, for a REST API it would be Api, for artisan commands it would be Cli. So the total directory structure might look something like this:

app/
----ToDo/
--------App/
------------Providers/
----------------ToDoServiceProvider.php
----------------ConfigServiceProvider.php
------------Validators/
----------------LaravelValidator.php
------------ValueObject.php
------------BaseModel.php
--------Domain/
------------List/
----------------EloquentList.php
----------------ListRepository.php
----------------ListService.php
----------------ListValidator.php
----------------Priority.php
------------Task/
----------------EloquentTask.php
----------------TaskRepository.php
----------------TaskService.php
----------------TaskValidator.php
--------Http/
------------Lists/
----------------ListController.php
----------------ListPresenter.php
----------------ListViewComposer.php
------------Tasks/
----------------TaskController.php
--------Infrastructure/
------------Lists/
----------------ListRepositoryCacheDecorator.php
----------------EloquentListRepository.php
------------EloquentTaskRepository.php

EDIT: Updated to reflect some additional classes I've outlined in subsequent posts

36 likes
NoorDeen's avatar

thank you @nrivero for reply . your name space structure makes me think about my application subsections .

@jekinney thank you for replay . for short namespaces it is good to right less code when use the classes , right ?

thank you @thepsion5 . this is very good and organized structure . can you tell me more details about each group responsibilities ?

maytham's avatar

@thepsion5 I like it, but would like to know what is the reason to not keeping the default structure?

thepsion5's avatar

Sure. I'll break this into a few different posts so each one isn't massive.

App Namespace

This is what I would consider the primary point of integration between my business logic, infrastructure logic, application ports (web, REST API, CLI), and Laravel. This is where I configure all of my dependency injection and store classes that are extended by the domain code without having any domain logic themselves. As a general rule, most of these classes will be abstract

  • Binding TaskRepository to EloquentTaskRepository via a service provider
  • Binding configuration data from one of Laravel's config files to a class that requires it as part of its constructor[1]
  • Creating an abstract LaravelValidator class that fulfills an interface without containing the actual rules for business logic validation
  • Creating a BaseModel class that provides shared functionality to my entities
  • Creating specific application-level services (not domain services) that rely on Laravel, such as utilities for moving files[2]
  • Creating abstract classes used by the various ports, for example an ApiController that has helper methods to transform responses, return API-specific error codes, embed meta information, etc

[1] For example, I may have a Validator that relies on being supplied an array of valid Task Categories defined in a configuration file. The constructor accepts that array of categories and I use a service provider to bind them:

//ToDo/App/Providers/ConfigServiceProvider.php
public function register()
{
    $categories = $this->app['config']->get('todo.categories');
    $this->app->bind('ToDo\Domain\Tasks\TaskValidator.php', function($app) 
    {
        $categories = $this->app['config']->get('todo.categories');
        $factory = $this->app->make('Illuminate\Validation\Factory');
        return new TaskValidator($factory, $categories);
}

[2] There's probably disagreement on this, but I believe that my domain logic shouldn't care what directory a file is in as long as it's capable of accessing said file. Therefore, the service for locating files is an infrastructure or application concern

20 likes
thepsion5's avatar

Domain Namespace

Put simply, this is where all of my business logic lives. Entities, Value Objects, Validators, Specifications, all the functionality that actually delivers value to the client will go here. Ideally, my entities would be POPO's (Plain Old PHP Objects) and not rely on Eloquent, but so far that's been difficult to make work well so I tend to use Eloquent for my entities - this is the one area where I egregiously violate SRP. But the ToDo\Domain\List namespace would have the following:

  • EloquentList - A List entity, I'd typically have mutators for Value Objects . If we want to consider the List entity an Aggregate Root, it would automatically have all of it's tasks loaded

  • Priority - A self-validating Value Object containing the List's priority. It might accept a numeric range from 1-10 or something simpler like "Low", "Normal", or "High"

  • ListRepository - A Repository interface with methods like findById($id), store($list), setPerPage($perPage = 0), sortBy($field, $direction = 'DESC'), existsByName($name) things of that nature.

  • ListService - This is the primary class my ports will be interacting with. If this functionality is complex enough, I'll break it from one class into several, others, maybe even individual Use Case classes[3], but for a small app a single service class is fine.

  • ListValidator - This is a validator responsible for performing validation that requires external data, which we can't do with the entity or value object. An example might be ensuring an List's name is unique among saved lists (which requires the repository as a dependency and as such can't be done as part of the entity).

All these things should only change based on what my client tells me. Any technical changes should go into abstract classes that the domain classes extend from or go into implementations of interfaces in the domain namespace.

19 likes
thepsion5's avatar

Http Namespace

This is where all the logic that connects my application to someone's web browser should go. If it's involved in responding to HTTP requests, it should live here. This might include the following:

  • ListController - Fairly self-explanatory. This might extend from an abstract controller class in the App namespace if necessary, and would have the ListService class injected into it. It would be responsible for catching validation exceptions thrown from the ListService class and handle them by redirecting and sending errors to the view.

  • ListPresenter - If we wanted to add html-specific formatting to lists, like formatting dates or turning the priority number into a more readable label, this functionality would go here. The controller would be responsible for creating instances of this class and wrapping the EloquentList entity in it before passing it to the view

  • ListViewComposer - If there is additional data we need to attach to one or more list-specific views, it would live here. This can be just about anything and can even have various application/domain services injected into it

This is just one "port" of my application. If I had Artisan Commands, or a REST API there'd be another namespace for it containing all the relevant classes.

17 likes
thepsion5's avatar

Infrastructure Namespace

Anything related to persistance will be in this namespace. The most obvious thing to go here would be repository implementations. In this particular example:

  • EloquentListRepository - This is the eloquent-specific implementation of the ListRepository interface in the domain namespace.

  • ListRepositoryCacheDecorator - This implements the same interface as the repository and acts as a decorator that adds caching functionality.

Other things that might go in this namespace: a ListDatabaseMapper class, if I was using the Data Mapper pattern instead of Eloquent. Usually this namespace is relatively sparse.

16 likes
thepsion5's avatar

@maytham If we're talking about Laravel 4, I use a different structure because it just doesn't fit my needs. Any moderately-large application is going to be vastly underserved by just having model and controller directories. IIRC, Laravel 5's structure is actually pretty close to what I use.

@alnour_altegani PSR-4 actually, but I think I could use either in this case and they'd behave identically.

7 likes
jekinney's avatar

@alnour altegani Not really less code, but if you do need to dig into something 6 months later, trying to remember is a bear. so having a namespace (for me) only a few files deep helps while some people who document their structure better may not have this issue....

DarkRoast's avatar

@thepsion5 I was wondering if the app structure you demonstrated was related to the hexagonal architecture?

Great posts by the way!

1 like
thepsion5's avatar

@WookieMonster - Yep, it's inspired by Hexagonal Architecture, though Domain Driven Development has similar concepts. I think the biggest difference may be that the code supporting my adapters (abstract controllers etc, etc) lives in the App namespace.

I'm not 100% set on that, but my thinking is it reduces the mental workload to see what each port is actually doing. I see Http\Tasks\TaskController, Http\Tasks\TaskPresenter, Http\Tasks\CreateTaskForm without having to mentally filter out AbstractController, AbstractHttpForm, etc.

3 likes
uxweb's avatar

@thepsion5 Woooow man, this is a great information about structure, you should write an article or a book about this. I appreciate your time and effort to write your knowledge. Thank you so much!!.

uxweb's avatar

@thepsion5, with this great structure, where do you put your routes.php file, is there one by app when you have more than 1 app under the "/app" directory or how do you manage them?

Thanks!

NoorDeen's avatar

@uxweb if you have Http or Api implementation for your application you can put your routes.php there .

about more than one app under the app directory you mean component or subsystem, right ? if this is your case you can make laravel package for every "component" or "subsystem" . or at least that what I do now .

1 like
jekinney's avatar

@AlnourAltegani

Definatly what I do too add "packages" such as a blog, discussion board etc as Laravel Packages through composer same as you would add some of the Laracast's repo's. Once you get the foundation projects done correctly adding those "packages" and running a few commands to create the migrations etc and with in minutes you have a full application with almost no code (but charge the customer full price).

1 like
singxint's avatar

I usually divide large apps into 5-7 namespaces, all starting with an app-wide namespace.

Roni's avatar

@thepsion5,

This is a really solid contribution to newbs to Laravel, like myself. Thanks. I have nothing to really contribute, but I wanted it to show up on "my threads" so I could come back to this whenever I want to reference it. I'd add a good feature for this forum would be a favourites option, and possibly some thread oriented notes, so we don't have to leave useless comments to keep track of them.

Happy Holidays -Roni

xingfucoder's avatar

Thanks @Ruffles for sharing, the Culttt website is a great source for learning about PHP, DDD, and Object Oriented and Design Patterns.

1 like
xingfucoder's avatar

Hi @thepsion5, I have some questions:

In the Domain Namespace you put the following reference Use Case classes[3] , is this explained somewhere in the post? As I know, Use Classes could be interpreted as commands. What do you think? Would be great to see working this structure with the new Commands and Handlers classes, the new HTTP folder, ..., although the HTTP folder could be confused by some users with the HTTP Namespace of our app.

Another question is related with the Factories, where is the best place to put them? Some people like to put within the Repository the create() method but I think that it is not a repository task, but you need to create a FactoryObject and place it within the Infraestructure Namespace.

The last question is about the Validators. I saw that you put some validators in the Application Namespace and others related with the Domain Namespace classes. What would be the difference?

Thanks in advanced. Your reference tips about DDD are greats.

thepsion5's avatar
  1. Use Cases are basically commands, I've experimented with that naming scheme just to see if it was more intuitive and less easily confused with artisan commands. In the end I don't think it made a difference so I went back to calling them commands. In a Laravel 5 application I'd probably call the "Http" namespace "Web" to avoid confusion.

  2. Factories are all about putting objects together and then providing them to the rest of your application. To me that falls under the same category as Service Providers, so I'd put them in the "App" namespace. This is different than infrastructure, which is about connecting your application to things outside the language like a SQL database, the filesystem, Redis, etc. That being said, Entities shouldn't have external dependencies, so I'd be concerned if they warranted a separate factory class to build them.

  3. The validator class in the App namespace contains all the validation code except the validation rules and is abstract. The validator classes in the domain namespace contain only the validation rules and anything else it needs to do domain-specific validation.

4 likes
davorminchorov's avatar

@thepsion5 I have a question, where do you put stuff connected to Authentication/ACL? (Users, Roles, Permissions etc) Do you put it in a different namespace/package or put all of the stuff where it belongs similar to the ToDo list example? Do you split the application according to the bounded contexts? (if the application is bigger than a todo list or a blog)

Let's say that you have to develop a hospital application as a domain, would the structure be the same?

nolros's avatar

@thepsion5 wow man I did not get your post from a week ago until I read this post. Thank you for sharing. Man when I think I see the bar I only realize it visibility to the first step of steps that gets me to see the bar.

A question for you and the team. When you are this deep into OOP best practices and patterns why stay with PHP versus C# or Java where the language truly embraces the edge of OOP? I assume the answer is best practice programming is best practice in any language?

thepsion5's avatar

@nolros And all of our web applications are built in PHP, and while I'm the primary developer in my division there are a few people who write PHP part-time and could contribute if needed. I've worked in Java and C#, so I could write applications with those if I had a few weeks to warm up and relearn the syntax and language features. But any project in C# or Java would have a Bus Factor of 1. Also I hate how ridiculously verbose Java is.

And honestly, while there are a few things that I would love to see in PHP from other languages (scalar typehints, generics, and operator overloading would be my top 3), I can still get 95% of the way there. Honestly the dumb inconsistencies in method names bother me way more than any of PHP's OO limitations.

@Ruffles Authentication logic (login/logout, passwords, etc) I usually put in the App namespace, since it's not quite domain logic and almost all of it is implemented by Laravel anyway. ACL logic, however, I would put in the domain namespace. However I haven't developed anything major with complex permissions (most are typically public/admin or basic user/admin) so I can't speak to how well it works.

1 like
xingfucoder's avatar

Hi @Ruffles, I only would put the ACL or another Authorization or Authentication logic within your Domain Layer if is part of the Domain Ubiquitous Language, and your application is related with that logic. If that logic is only a capability of the core application, or a framework, to ease the accessing process, you need to use, as @thepsion5 commented here, the App namespace.

2 likes
Next

Please or to participate in this conversation.