0

I am thinking about scenario in a way of Domain Driven design, where I have entity, lets say Cv (Curriculum vitae), which state is saved in database via repository.

Now I need to store part of the Cv in another system (ElasticSearch), which is crucial for whole app functionality like searching.

How to handle it? I am thinking about these 2 options:

1. Use domain service IndexCvGatewayServiceInterface (as interfaces implemented in infrastructure)

class CvEntity
{
    public function approve(CvRepositoryInterface $cvRepository, IndexCvGatewayServiceInterface $indexService)
    {
        $cvRepository->update($this);
        $indexService->update($this);
    }
}

2. Listen to domain event (create infrastructure listener)

class CvEntity
{
    public function approve(CvRepositoryInterface $cvRepository, EventDispatcheInterface $dispatcher)
    {
        $cvRepository->update($this);
        $dispatcher->dispatch(new CvApprovedEvent($this));
    }
}

I like option 2. because it separates logic for non state change purposes into infrastructure, but there is also concern, that we should know about searching as important part of our app.

Mariyo
  • 486
  • 7
  • 15

1 Answers1

0

You're facing here Write and Read model. Ideally after persist your entity/aggregate in the write model you should dispatch the uncommitted events of this entity and listing/subscribe to them to generate the projections (partials in elastic in your use case). For reference: https://github.com/jorge07/symfony-5-es-cqrs-boilerplate/blob/symfony-5/src/Infrastructure/User/ReadModel/Projections/UserProjectionFactory.php#L17 IMO, Entity should not contain the repository.

Jorge
  • 197
  • 7
  • Thank you for participation. I can see some new words to me, could you give me some links to read more about projections and read/write models please? – Mariyo Jan 19 '21 at 20:15
  • Btw, Entity does not own repository, its provided as method argument – Mariyo Jan 20 '21 at 07:03
  • 1
    By passing the repository to the entity you're adding persistence responsibility to the model. Something it should not care about. Instead, add the event dispatcher as dependency of your repository and pass the entity to the repository method. Entity is about domain, repository about persistence. This is well managed here https://github.com/broadway/broadway/blob/master/src/Broadway/EventSourcing/EventSourcingRepository.php#L73 – Jorge Jan 20 '21 at 21:07
  • 1
    About the read and write model https://dev.to/barryosull/projection-building-blocks-what-youll-need-to-build-projections--5g1n – Jorge Jan 20 '21 at 21:15