Publikowanie zdarzeń: z poziomu DAL czy logiki?

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

  1. Zastanów się, czy Twoje zdarzenia mają charakter techniczny, czy biznesowy. Jeśli to drugie – powinny być publikowane w warstwie logiki.
  2. Nie traktuj bazy danych jako centrum Twojej domeny. Podejście CRUD często prowadzi do błędów wynikających z braku kontekstu biznesowego.
  3. 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.

Autor wpisu

blog@orbisbit.com

Komentarze

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Sprawdź również