Event Driven Architecture for Dummies

Aveti careva experienta cu trecerea la dezvoltarea unui sistem pe arhitectura event driven dupa lucrat doar in paradigma Domain Driven ?

Am un proiect in minte care are mai multe componente care s-ar preta pt event-driven cum ar fi un pipeline de ingerare si procesare de date de la senzor IOT si alte date disparate. De asemenea charts vor fi destul de importante pt afisarea datelor.

Acelasi proiect are nevoie si de o parte “statica” (for lack of a better word) care trebuie dezvoltata the usual way.

Cum ar trebui sa imi schimb perspectiva pentru a face asta? La ce trebuie sa am grija? Ce pitfalls sunt?

Mersi anticipat si Sarbatori Fericite!

Cred ca aici este o confuzie.

Domain Driven si Event Driven nu sunt mutual exclusive.

In principiu, Domain Driven inseamna ca logica de business este abstractizata/structurata intr-un anumit fel pentru a putea avea o mai mare libertate si claritate asupra ce e domeniu si ce e cod specific implementarii.

Event Driven, dupa cum ii zice si numele, este un model arhitectural care e folosit in principal pentru a comunica intre servicii decuplate prin evenimente; unde ai 3 actori mari in infrastructura: producatorii de evenimente, routerul/brokerul de evenimente si consumatorii de evenimente.

Domain Driven e mai mult o colectie de patternuri pentru cod/logica de business, iar Event Driven e o arhitectura care permeaza codul si mai ales infrastructura.

Poti sa ai cod scris dupa principiile DDD si pentru serviciile care comunica prin evenimente.

7 Likes

Intr-adevar, nu e cea mai corecta comparatia in materie de una contra cealalta, eu ma refeream doar la o infrastructura mai degraba monolitica, care nu e bazata pe events.

Ma intereseaza daca a trecut cineva de la paradigma monolitica in care functionalitatea e mai tightly coupled catre event driven unde se duce spre loosely coupled, si ce challenge-uri a intampinat de orice fel.

Am trecut de mai multe ori prin asta. Cateva idei mai jos.

  • DDD nu e chiar acelasi lucru ca EDA insa in DDD vei ajunge inevitabil sa folosesti Domain Events. Care chiar daca isi au originea in Domain, tot e best practice sa le persisti pe o bucata de infrastructura gen Kafka la un moment dat. Implementarea ca sa se incadreze in paradigma DD este un detaliu minor de implementare, dar daca vrei mai multe informatii aici pot detalia in alta postare.
  • E evident ca trebuie sa stapaniti bine de tot limbajul de business. Dar strict facand referire la ce ai postat aici as zice asa: Separa aplicatia bine in Bounded Contexts. Pana aici pot identifica Ingest Pipeline BC, Data Processing BC, Charts BC. Ai mare grija cu tzeapa numita conspirativ “DRY”. Pentru ca de ex. modelul de User poate exista(si e normal sa fie asa) in mai multe bounded contexts. Una inseamna User pentru PIpeline BC, alta pentru Data processing si alta pentru Charts. Au proprietati diferite. Pot share-ui un ID, poate email…insa ai grija ca sunt modele diferite.
  • comunicarea intre BC ar trebui sa o gandesti sa fie via Domain Events cum am mentionat mai sus. Cum faci asta? Pai un exemplu concret ar fi un event gen “LoginSuccess”. Aceasta va fi nimic altceva decat o Interfata in domeniu, cu metodele email() si occuredOn(), de exemplu. Apoi in infrastructura creezi o clasa concreta care implementeaza chestia asta si la un moment dat in controller, deci tot in infra, vei avea un dispatchEvent(“LoginSuccess”). Bineinteles, aici trebuie sa gandesti un mecanism care va persista acele events intr-o componenta externa gen Kakfa, RabbitMQ sau altele. Apoi depinde de business daca sunt interesati sa stie cate logins au existat in ultimele 24 de ore, si alte chestii de business pe care le rezolvi cu unul sau mai multi consumers in infra care vor apela un serviciu concret din layer-ul de application.
  • gandeste Use-cases pentru fiecare BC in parte. Aici respecta S din SOLID intocmai. Evita numele generice. De ex. OrderService nu este ok si nu face bine nimanui. Implica existenta unui God object si nici nu imi doresc sa deschid asa ceva in IDE. Best practice: CreateUserService, ViewUserProfileService, SearchUsersByCriteriaService, DeleteUserService, etc.
  • foloseste Value Objects. Au scop de validare a domeniului de business. Te vor ajuta mult in cod plus ca e best practice DDD.
  • foloseste DTOs pentru Request/Response. Nu stiu daca are sens sa explic mult aici. Gandeste-te ca un serviciu gen CreateUserService va avea nevoie cel mai probabil de un CreateUserRequestDTO(parametri TBD) si va raspunde cu un CreateUserResponseDTO.
  • partea statica e doar UI. Tine de infrastructura. Don’t overthink it. Daca vrei o separare si mai mare, poti avea diferite “applications” in partea de infra. Applications pot deservi un mod de folosire a aplicatiei tale, adica Web, CLI, Mobile si altele daca mai sunt.
2 Likes

Probabil nu m-am exprimat bine, un model l-as considera CRUD si celalalt DDD I guess.

Am un inceput de experienta cu ambele, si Domain Driven Events si Kafka. Cu ce mi-e greu sa ma obisnuiesc e conceptul de topic per domain event, sau trebuie segregat putin mai high level, in loc de UserLoggedIn mai degraba UserLogins sau similar?

Asta am inteles-o cat de cat, in principiu un user pentru sales context nu are aceeasi informatii ca un user pt authentication context.

Am inteles, asta e un concept foarte interesant si mi se pare ca decupleaza foarte bine aplicatia.

Aceste service-uri ar fi ceva gen Command Handlers in CQRS sau e putin mai low level decat command handlers?

Astea nu prea le-am inteles niciodata. Le inteleg ideea cred, de refolosire across a context?

Cu partea asta ma lupt si mi se pare cel mai diferit in cele doua paradigme.

Multumesc mult pentru raspunsul detaliat!