Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DDD, Event store, UI

I have a project which is designed or at least should be according to the well known DDD principles.

  1. Back - DDD + CQRS + Event Store

  2. UI - ngrx/store

I have a lot of questions to ask about it but for now I will stick to these two:

  1. How should the UI store be updated after a single Command/Action is executed ?

a) subscribe to response.ok

b) listen to domain events

c) trigger a generic event holding the created/updated/removed object ?

  1. Is it a good idea to transfer the whole aggregate root dto with all its entities in each command / event or it is better to have more granular commands / events for ex.: with only a single property ?
like image 506
Ivelin Matev Avatar asked Dec 07 '22 16:12

Ivelin Matev


1 Answers

How should the UI store be updated after a single Command/Action is executed ?

The command methods from my Aggregates return void (respecting CQS); thus, the REST endpoints that receive the command requests respond only with something like OK, command is accepted. Then, it depends on how the command is processed inside the backend server:

  • if the command is processed synchronously then a simple OK, command is accepted is sufficient as the UI will refresh itself and the new data will be there;
  • if the command is processed asynchronously then things get more complicated and some kind of command ID should be returned, so a response like OK, command is accepted and it has the ID 1234-abcd-5678-efgh; please check later at this URI for command completion status

At the same time, you could listen to the domain events. I do this using Server sent events that are send from the backend to the UI; this is useful if the UI is web based as there could be more than one browser windows open and the data will be updated in the background for pages; that's nice, client is pleased.

About including some data from the read side in the command response: this is something that depends on your specific case; I avoid it because it implies reading when writing and this means I can't separate the write from the read on a higher level; I like to be able to scale independently the write from the read part. So, a response.ok is the cleanest solution. Also, it implies that the command/write endpoint makes some query assumptions about the caller; why should a command handler/command endpoint assume what data the caller needs? But there could be exceptions, for example if you want to reduce the number of request or if you use an API gateway that do also a READ after the command is send to the backend server.

Is it a good idea to transfer the whole aggregate root dto with all its entities in each command / event or it is better to have more granular commands / events for ex.: with only a single property ?

I never send the whole Aggregate when using CQRS; you have the read-models so each Aggregate has a different representation on each read-model. So, you should create a read-model for each UI component, in this way you keep&send only the data that is displayed on the UI and not some god-like object that contains anything that anybody would need to display anywhere.

like image 147
Constantin Galbenu Avatar answered Dec 10 '22 05:12

Constantin Galbenu