webdevilopers / php-ddd

PHP Symfony Doctrine Domain-driven Design
201 stars 10 forks source link

DDD directory structure using Symfony Flex (4/5) #36

Open webdevilopers opened 4 years ago

webdevilopers commented 4 years ago

Symfony 4/5 create an App namespace by default refering to alle files inside the src folder. Initially a Controller folder may be created. When adding the doctrine recipe it will add Entity, Repository and Migration. Prooph Event Store will add a Command namespace for instance.

Currently we remove the unused folders e.g. "Entity" since we only use the DBAL not the ORM. Required folders e.g. "Controller" are moved to src\Acme\BoundedContext\Infrastructure\Symfony. It could also be Framework.

But after creating some new projects moving the files and reconfiguring the Symfony autowiring we are thinking about skipping this task. We only want to focus on adding our bounded context and (sub-)domains to the organization folder e.g. Acme and keep the Symfony App as it is for a better quickstart.

What do you guys prefer?

Also see:

rubenrubiob commented 4 years ago

I think that, for removing the App namespace, you have to change composer psr-4 autoloader, too.

I would rather skip the App name if it is something that does not make sense for your applications. My applications usually have the namespaces:

Is it so tedious to remove the App namespace? Perhaps it is if you create many applications.

Maybe it is possible to automate it somehow? I am thinking about a script, but maybe it is possible to create a Symfony recipe that can be installed?

webdevilopers commented 4 years ago

A recipe or a short blog where to move and delete what would indeed be nice. Where do you put Symfony in your example -> Infrastructure\Symfony (or Framework or similar?)

rubenrubiob commented 4 years ago

It should be doable within blog post, but I do not have a blog where to post it 😅

I do not know what you mean exactly by where I put Symfony. Usually, Symfony is for the Controllers or CLI Commands, that live in the Ui folder, that it is Infrastructure.

In my infrastructure layer I have implementations for my Domain interfaces, and they belong in some higher namespace with the functionallity and the name of the library/framework. Below there is a screenshot of a folder structure of one of my projects, to make it clearer:

image

In the case I have more than one framework for persistence, for example, I have it organized like so:

image

Hope it helps!

Where do you put your libraries/frameworks?

webdevilopers commented 4 years ago

Similar to your approach. But we currently also have a Infrastructure/Symfony directory. In addition to that a Presentation layer which is equal to your "UI / UserInterface layer. But it also holds an Model namespace that holds all our read models as objects. This helps us communicating our read models and ensuring the projections were correctly applied since a lot of invariants for WRITE processes will rely on a the valid read model.

rubenrubiob commented 4 years ago

It sounds interesting.

How have you implemented those read models? What do they represent? Are they for mapping input prior to call your application services?

I do not apply fully CQRS, but I separate my write and read models. For instance, in a project I have a category tree of 3 levels, and I persist them all independently, because the business requires so. But when I query them, I perform a query that unifies the 3 levels into a read model. That read model lives within the Domain layer.

What I have in my UI layer are objects that map a request, from a form or an API, into an object, that is validated using Symfony validator within a controller resolver. The same object tells me if has passed the validation and, if so, I call my command bus getting the parameters from that object.

I do not know if I am making myself clear, but I can show you a minimal example, if you want :)

webdevilopers commented 4 years ago

Sure @rubenrubiob , maybe you could just open up a new issue "Where to put read models" on this repo and add your examples. We can discuss some solutions then. Looking forward to that.