In order to keep our code clean and follow the DDD pattern we are going to see how we must structure our files and classes in a Symfony Flex project.
As we see in our previous article our Controllers will be stored in
app/ folder because they are attached to the framework itself, but the rest of the code will be in our
This folder will contain our different domains and inside each domain we will store our domain, application and infrastructure code.
If we take a look, for example, to the Lead domain we find something like this.
└─ Leads ├─ Application │ ├─ Create │ ├─ CreateLeadCommand.php │ └─ CreateLeadCommandHandler.php ├─ Domain │ ├─ Event │ │ └─ LeadCreatedEvent.php │ ├─ Exception │ │ └─ DuplicatedLeadException.php │ ├─ ValueObject │ │ ├─ LeadCreatedAt.php │ │ ├─ LeadEmail.php │ │ ├─ LeadName.php │ │ └─ LeadUuid.php │ ├─ Repository │ │ └─ LeadRepository.php │ └─ Lead.php └─ Infrastructure └─ Persistence ├─ Doctrine │ ├─ Lead.orm.xml │ ├─ ValueObject.LeadCreatedAt.orm.xml │ ├─ ValueObject.LeadEmail.orm.xml │ ├─ ValueObjectLeadNameType.php │ └─ ValueObjectLeadUuidType.php └─ DoctrineLeadRepository.php
As you can see, inside the
Leads folder we have an
Infrastructure folder to store code depending on the software layer it belongs.
- In the domain folder we store our code and interfaces that has no dependencies with other folders or code.
- In the application we store our use cases, usually services, commands or queries with their own handlers.
- And in the infrastructure code we have implementations of the repository interfaces. Code that interact with our database or outside services. Also, we store here all configurations files needed for doctrine or Symfony.
This is a basic and clear way to structure your project in Symfony following DDD and Hexagonal Architecture. You can change some things like subfolder to group classes by type or not, as you prefer, but what it's really important it's to follow the same structure in all your domain and don't mix application, domain and infrastructure code together.
Remember that the entry point it's your application layer, then you go to the domain layer and with an interface you can finally call infrastructure code. If you follow this order everything will be testable and clean.
In the next article we will talk about Commands and Query and how to create the Command Bus in Symfony.