Powiedzmy, że mam aplikację, w której użytkownik może publikować zdjęcia. Najpierw w bazie zapisywane są metadane na temat zdjęcia (tytul, data publikacji itd.), a potem plik jest zapisywany fizycznie na dysku. Czy zapis pliku na dysku powinien być w handlerze komendy CreatePhoto
czy w handlerze zdarzenia PhotoCreated
? Jeśli mam przestrzegać SRP, to raczej to drugie, tylko czy to nie jest przykład sztucznego tworzenia eventu?
- Rejestracja:prawie 7 lat
- Ostatnio:ponad 2 lata
- Lokalizacja:Gdańsk
- Postów:647

- Rejestracja:ponad 21 lat
- Ostatnio:około 10 godzin
- Lokalizacja:Kraków
- Postów:1114
Raczej nie ma na to pytanie jednoznacznej odpowiedzi, jak zawsze to zależy od szerszego kontekstu i własnego doświadczenia.
Ostatnio natrafiłem na artykuł poruszający dość luźno właśnie ten problem z podziałem na komendy i zdarzenia:
Message design for event-driven architecture: anti-patterns and pitfalls

- Rejestracja:prawie 20 lat
- Ostatnio:około 11 godzin
Uwaga: teoretyzuję, bo nie bawiłem się w CQRS + ES w praktyce:
Nie wiem jak wygląda CQRS bez ES, ale przy ES musisz być w stanie odtworzyć stan aplikacji z samych zdarzeń, bo komendy nie są nigdzie zapisywane. W takim połączeniu komendy służą tylko do tego by wygenerować listę zdarzeń, a dopiero przy obsłudze zdarzeń zmieniamy stan aplikacji. Obsługa pojedynczego zdarzenia polega na najpierw zapisaniu zdarzenia, a potem ewentualnie modyfikacji stanu aplikacji gdzie indziej (jeśli przechowujesz w aplikacji coś więcej niż tylko zdarzenia, a prawie na pewno tak jest).

- Rejestracja:prawie 9 lat
- Ostatnio:ponad 2 lata
- Lokalizacja:UK
- Postów:2235
Tak jak kolega wyżej napisał- to zależy. Natomiast mam pytanie co do tego:
Jeśli mam przestrzegać SRP, to raczej to drugie(...)
Dla czego tak uważasz? Nie ma sensu pchać na siłę eventu (no chyba że stosujesz event sourcing, ale to inna bajka), a również nie wydaje mi się żeby fizyczne zapisanie na dysku lamalo SRP w tym przypadku (chociaż to czy i kiedy SRP jest łamane to sprawa bardzo dyskusyjna). Ewentualnie możesz mieć oddzielne polecenie i handlera do fizycznego zapisu.
Dodam jeszcze, że nie jestem pewny co do idei zapisywania czegoś na dysku w handlerze eventu. W takim przypadku mamy do czynienia z czymś co już zaszło, a więc taki handler może co najwyżej zaktualizować swoje dane (np. zapisać do bazy metadane jak i link do fizycznego pliku). Skoro (...) Created, to stworzony a nie częściowo stworzony. No ale raz jeszcze - to zależy

- Rejestracja:ponad 8 lat
- Ostatnio:około 3 godziny
- Lokalizacja:U krasnoludów - pod górą
- Postów:4706
Jeśli bawisz się w Event Sourcing. To eventy muszą być napisane tak, żeby:
- prawdopodobieństwo wywalenia przy odtwarzaniu było minimalne,
- żeby prowadziły do tego samego rezultatu,
- obsługa eventu była relatywnie szybka,
Odczytywanie czegokolwiek z dysku (IO) w event to recepta na katastrofę. Zapis/ odczyt może się nie udać, albo ktoś zmieni zawartość pliku, folderów etc.
(ale może u Ciebie coś takiego nie może zajść, prawdopodobieństwo jest nikłe).
Podejsćie dość klasyczne:
Komenda - coś co chcemy od systemu. W Command handlerze walidujemy dane itp. jak wszystko jest ok to tworzymy eventy (jedna komenda daje w wyniku zero lub więcej eventów).
Eventy są generalnie faktami (ostatnio u siebie zmieniłem nawet nazewnictwo na fakty, bo w powalonym DDD jest tyle typów eventów, że można się pogubić). I wiadomo, że się stało
. W eventach zasadniczo nie robimy już żadnych walidacji, IO, nie czytamy nawet daty obecnej, ani nie robimy całkiem losowych randomów.
Przy okazji: Kiedyś stowosowało się command sourcing, ale to było mentalnie trudniejsze. Trzeba było przed komendą zrobić wszystkie możliwe walidacje.
Przy okazji: Co do CQRS - ostatnio mnie wkurza. Albo przestałem rozumieć CQRS, albo to nonsens. Jak może operacjqa nie zwracać wyniku? To jest nawet niemozliwe :-), co więcej niepotrzebne.

- Rejestracja:prawie 9 lat
- Ostatnio:ponad 2 lata
- Lokalizacja:UK
- Postów:2235
Przy okazji: Co do CQRS - ostatnio mnie wkurza. Albo przestałem rozumieć CQRS, albo to nonsens. Jak może operacjqa nie zwracać wyniku? To jest nawet niemozliwe :-), co więcej niepotrzebne.
Przekonanie że operacja (komenda) nie może zwracać wyniku bierze się z mylenia podejścia command-handler, CQRS oraz event-driven. Są ze sobą powiązane (a konkretnie CQRS korzysta z command-handler), natomiast to nie to samo. Do tego w grę wchodzi jakieś sztywne trzymanie się nie-uniwersalnych zasad. Ktoś patrzy na DDD z wykorzystaniem ES i myśli że agregaty odbierają komendy i tworzą eventy, to w takim razie nigdzie indziej nie można zwracać wyników z handlerow. Z tym że command handler to coś całkowicie innego niż agregat, który w odpowiedzi na komendę tworzy eventa. W takim przypadku owszem, fundamentalnie błędne byłoby zwracanie jakiegoś wyniku ponieważ "z natury" podejście takie zakłada asynchronicznosc oraz eventual consistency.
Natomiast w każdym innym przypadku gdzie komenda jest zwykłym poleceniem zrobienia czegoś, a szczególnie polecenia wyciągnięcia danych to zwrócenie wyniku jest czymś jak najbardziej normalnym. Warto tutaj dodać że przeważnie komenda nie pytająca o dane, a nakazująca ich zapisanie (np. ConfirmOrder) nie zwróci wyniku, bo brak wyjątku będzie sam w sobie wynikiem wskazującym na pozytywne zakończenie operacji.
- Rejestracja:około 6 lat
- Ostatnio:około 6 lat
- Postów:2
Ktoś patrzy na DDD z wykorzystaniem ES i myśli że agregaty odbierają komendy i tworzą eventy, to w takim razie nigdzie indziej nie można zwracać wyników z handlerow
Aggregaty nie odbierają żadnych komend to serwisy lub dedykowane handlery odbierają komendy.
ostatnio u siebie zmieniłem nawet nazewnictwo na fakty, bo w powalonym DDD jest tyle typów eventów, że można się pogubić
Możesz mi wyjaśnić, o co ci chodzi?
Przy okazji: Co do CQRS - ostatnio mnie wkurza. Albo przestałem rozumieć CQRS, albo to nonsens. Jak może operacjqa nie zwracać wyniku? To jest nawet niemozliwe :-), co więcej niepotrzebne.
Jeśli masz na myśli architekturę, która nie bazuje na eventach to masz rację.
Aventus