Publikowanie zdarzeń, gdzie to robić? Z poziomu operacji CRUD (w DAL) czy w warstwie logiki? Poznaj zalety i pułapki obu podejść oraz najlepsze praktyki.
Jaki jest problem?
Publikowanie zdarzeń domenowych to kluczowy aspekt dobrze zaprojektowanej architektury. Ale kiedy dokładnie powinny być emitowane? Czy zdarzenia powinny wynikać bezpośrednio z operacji CRUD, czyli być publikowane w DAO / Repozytorium, czy może poprawniejsza jest emisja w warstwie logiki: w serwisie, bądź komendzie? Odpowiedź na to pytanie ma istotny wpływ na spójność i elastyczność systemu.
Publikowanie zdarzeń z poziomu CRUD
Publikowanie zdarzeń z poziomu operacji CRUD oznacza ich emisję w momencie zmian w bazie danych. Może ono mieć miejsce w klasie, która odpowiada za komunikację z bazą. Oto prosty przykład:
class UserRepository {
constructor(
private readonly eventBus: EventBus,
private readonly dao: DbConnection<User>,
) {}
async save(user: User): Promise<void> {
await this.dao.save(user);
this.eventBus.publish(new UserUpdated(user.id));
}
}
Podejście to jest intuicyjne i łatwe do zaimplementowania. Problem pojawia się, gdy chcemy wprowadzić logikę biznesową. Nie mamy pewności, dlaczego operacja się wydarzyła – czy była wynikiem konkretnej intencji użytkownika, czy może była tylko techniczną synchronizacją?
Zdarzenia w warstwie logiki
Alternatywnie, możemy publikować zdarzenia na poziomie serwisów aplikacyjnych / komend (jeśli stosujemy agresywne podejście CQRS):
class UpdateUserHandler {
constructor(
private readonly userRepository: UserRepository,
private readonly eventBus: EventBus,
) {}
async execute(command: UpdateUserCommand): Promise<void> {
const user = this.userRepository.findById(command.userId);
user.update(command.newData);
this.userRepository.save(user);
this.eventBus.publish(new UserUpdated(user.id));
}
}
Tutaj zdarzenie jest publikowane w odpowiedzi na określoną intencję biznesową. Takie podejście pozwala na lepszą enkapsulację logiki i uniezależnia system od samej struktury bazy danych.
Publikowanie zdarzeń: co wybrać?
Oba podejścia mają swoje zalety i wady. Publikowanie zdarzeń z poziomu CRUD jest szybkie i proste, ale często prowadzi do niespójności semantycznej. Z drugiej strony, emisja zdarzeń z poziomu komend / serwisów lepiej odzwierciedla intencje użytkownika i ułatwia rozwój systemu, ale wymaga dodatkowej warstwy logiki.
Najlepsze praktyki
- Zastanów się, czy Twoje zdarzenia mają charakter techniczny, czy biznesowy. Jeśli to drugie – powinny być publikowane w warstwie logiki.
- Nie traktuj bazy danych jako centrum Twojej domeny. Podejście CRUD często prowadzi do błędów wynikających z braku kontekstu biznesowego.
- Unikaj nadmiarowego publikowania zdarzeń. Przemyśl, czy rzeczywiście każda zmiana w bazie powinna generować zdarzenie.
Podsumowanie
Decyzja, gdzie publikować zdarzenia, nie jest trywialna. Podejście CRUD może wydawać się wygodne, ale w dłuższej perspektywie to warstwa logiki zapewnia większą elastyczność i spójność biznesową. Warto inwestować w dobre modelowanie domeny – ułatwia to zarówno rozwój aplikacji, jak i jej przyszłe skalowanie.
Dodaj komentarz