jorge07/symfony-6-es-cqrs-boilerplate

How would you add a relation in a use case?

razvan-tache opened this issue · 3 comments

If you would have an entity, let's say Profile, that contains an User.
How should the createProfile use case look?
It should use the UserRepository and ProfileRepository? Fetch the user, and then create a profile for that User?
Or should the bus be used?

My suggestion is to start by modeling your domain, then jump into your application layer and finally the read model.

Domain

I use to do the following exercise when modeling aggregates:

  • How can live without the other?

Let's say User can't live without Profile. That converts Profile in your aggregate root and user into his child. The how to is here in broadway examples.

That said, you only need here a ProfileRepository as is the entity in charge of all the aggregates (because is the aggregate root). How you model here your Domain Events is up to you. keep in mind that child entities should fire is own events so you should not raise a User specific event from Profile.
Let's do it with examples:

Let's asume Profile and User are a 1-1 relation. Means there's no sense to fire a ProfileWasCreated and UserWasCreated event at the same time as you're firing two events for the same action.

Profile::create() -> fires a ProfileWasCreated event

Now asume password lives in User entity

Profile::changePassword() -> call $this->user->changePasword() -> And is thisUser function who fires UserPasswordWasChanged event as Profile just acts as proxy entity here.

Application

Knowing the dependencies we know already that we need our ProfileRepository in the command handler to check for possible duplicates (idempotency) and for persistence.

ReadModel

In your EventBus a ProfileWasCreated event is now published. Use a Subscriber to get this event and model your read model as you want. Here you can have a UserRepository, ProfileRepository, it really depends of your needs.
This repo has a branch example-relations you can look for references and some pro tips to avoid extra queries like this one of createReference in the ProjectionFactory aka event subscriber

Thanks for the fast answer. This makes a lot of sense. I will look over the examples!

I'll close the issue. Feel free to reopen if needed. I'll also think about add this to the documentation