Istnieje wiele opinii na temat CQRS z DDD i tego, co składa się na każdy komponent. Nie zacząłem jeszcze szukać informacji na temat pozyskiwania zdarzeń, więc poniższa lista nie zawiera niczego związanego z tym. Chociaż wgląd w ES byłby interesujący.Role i zadania komponentu CQRS z interfejsem API REST
Do tej pory posiadam następujące komponenty o powiązanych obowiązkach (patrz poniżej). W poniższych punktach przedstawiłem kilka pytań.
REST Punkty końcowe/Application
- Otrzymuj żądanie od użytkownika/UI/etc
- budowy i wysyła odpowiednie polecenia
- Jeśli polecenie wymaga wartości od innych ograniczonych kontekstach, a następnie wykonać odpowiednie Finder wywołania wymagane do prawidłowego utworzenia polecenia (np. zamówienie wymaga identyfikatora użytkownika)
- W przypadku GET: odpowiedni Finder nazywa się
- Finders siedzą na tym poziomie aplikacji. Strona zapisów Bounded Contexts (program obsługi komend, agregacja, fabryka, usługa domeny itp.) Nie powinna wywoływać Finderów. Utrzyma to hermetyzację i przekazanie do komend tylko wymaganych danych (zamiast pełnych DTO) staje się skromną warstwą antykorupcyjną.
- Na przykład:
AggregateId idZamówienia = AggregateId.get(); AggregateId userId = finder.findUserAggregateIdByEmail (e-mail); dispatcher.fire (nowy CreateOrderCommand (orderId, userId, orderItems));
poleceń
- Zmiany w domenie są dokonywane za pomocą poleceń dyspozytorskich
- Polecenia są niezmienne i zawierać dane niezbędne dla ograniczony kontekst zmienia to stan lub wyjątek
- Komenda dane wejściowe można zweryfikować podczas tworzenia obiektu, aby uniknąć wysyłania nieprawidłowych poleceń.
- Na przykład:
new CreateOrderCommand(orderId, userId, orderItems);
poleceń Handler
- może też z powodzeniem stosować komendy lub wyjątek Handler
- Nie może być tylko jeden obsługi poleceń dla każdego polecenia
- Handler załaduje lub utwórz kruszywa Katalog główny (repozytorium lub fabryka agregatów)
- Program obsługi zastosuje to polecenie do agregatu root
- Transakcja handlowa s z repozytorium
- Nie powinien uruchamiać komend (w kontekście z ograniczeniami)
- Czy polecenie obsługi powinno wysyłać zdarzenia? Na przykład po pomyślnym zapisaniu do bazy danych? A może to wyłącznie odpowiedzialność Aggregate'a?
Kruszywo Fabryka
- oddaje logikę wymaganą do zainicjowania się Agregat Korzeń poprawnie
- Fabryka może uzyskać dostęp do repozytorium
- powinny dostępie fabryka Domain Services?
- Na przykład:
factory.createOrder(orderId, userId, orderItems);
Kruszywo root/Kruszywa
- zawiera logikę domeny, stan i zachowanie
- odpowiedzialny za dysponowanie Wydarzenia
- Kruszywo głównej hermetyzuje dostęp do kruszywa
- Korzeń agregatu powinien mieć identyfikator, który unikalnie dentifies to
- nie powinien wchodzić w interakcje z usług zewnętrznych (innych niż wydawcy zdarzenia)
- na przykład:
order.cancel();
Domain Służby
- zawiera co nie bardzo pasuje w Korzeń agregatu
- Z jakich składników może współpracować usługa domeny?
- Czy usługi/zdarzenia związane z usługą domeny powinny być uruchamiane?
- Na przykład: Nie wiesz, czego użyć, pierwszy punkt powyżej jest w najlepszym razie niejasny. Większość zachowań jest ładnie w Aggregate lub można je osiągnąć poprzez Sagi/Zdarzenia/Polecenia. Jaki byłby tutaj ważny przykład?
Repository
- dba o załadunku/zapisywania/aktualizacji/etc Nasze kruszywa
- Na przykład:
repo.load(orderId);
imprez
- Przedstawia coś, co miało miejsce w agregacie (lub obsługi poleceń, etc, jeśli mogą one także ogień zdarzenia)
- wydarzenia są niezmienne
- Inne ograniczony konteksty w systemie można użyć zdarzenia do podejmowania decyzji
- Na przykład :
new OrderCancelledEvent(orderId);
Event Handler
- reaguje na zdarzenia tha t odbyła
- Może istnieć wiele obsługi zdarzeń dla pojedynczego zdarzenia w tej samej lub różnych kontekstach ograniczonych
- może współdziałać z usług infrastrukturalnych: OrderCancelled => OrderCancelledHandler => EmailService.sendEmail()
- może wystrzelić nowe polecenia
- Może porozmawiać z Finders
- Gdy obsługa zdarzeń uruchamia polecenia, rozmawia z Finderami i współdziała z infrastrukturą, ma ona charakter podobny do Sagi (lub zachowania REST Enpoint). Poza tym jest to reakcja na pojedyncze wydarzenie, a nie łańcuch/zestaw zdarzeń.
Saga
- Utrzymuje procesu biznesowego, który siedzi po drugiej stronie tej samej lub wielokrotność ograniczony kontekstach (współrzędne)
- odbiera zdarzenia
- Utrzymuje stan łańcucha/zestaw zdarzenia
- Normalnie stan jest zachowywany
- Limit czasu można ustawić, aby sprawdzić/zmienić stan (może mieć pojęcie czasu)
- Stany mogą wywoływać efekty uboczne, takie jak: wypalanie poleceń, rozmowa z Finderami, interakcja z usługami infrastruktury (np.e-mail)
- Na przykład: czekać na OrderShipped i OrderReceived wydarzenia => ogień CancelOrderCommand Poczekaj na OrderCancelled => rozkaz ogień odwołany email
Finder
- do odtworzenia readmodel z kontekst (y)
- Ogólnie zwraca obiekty typu Data Transfer Object (DTO)
- Fin nie należy szukać po stronie zapisu naszej aplikacji (mniej sprzężenia)
- Model zunifikowanej bazy danych Single (odczyt + zapis): Finder może wywoływać inne lokalizatory (w różnych kontekstach), aby zaspokoić zagnieżdżone obiekty.
- Przeczytaj konkretne znormalizowany Database model: Finder otrzyma danych w jednym wywołaniu Database
- na przykład:
finder.findOrdersOnDate(date);
Infrastructure Services
- promocji z infrastruktury: db dostępu, wysyłać e-maile, kolejki komunikatów, itp
Pytanie
czy jest to dokładne zestawienie składników vs. obowiązków? Czego brakuje i co należy przenieść? Mogę zaktualizować listę z odpowiednimi odpowiedziami.
["Implementing Domain-Driven Design"] (https://vaughnvernon.co/?page_id=168) autorstwa Vaughna Vernona dostarcza szczegółów technicznych dotyczących każdego z tych komponentów. Polecam go jako bardzo przydatne źródło oprócz Eric Evans "Domain-Driven Design". –
Przypadkowo znalazłem artykuł Vaughna Vernona zeszłej nocy. Bardzo interesujące! Będę kupować książkę. Czy chcesz dodać coś do listy na podstawie książki? –