DDD, Rest API i ogólnie o strukturze projektu

0

Cześć,

zacząłem pisać dość proste API restowe do tworzenia rezerwacji, co by ułatwić pracę rodzicom, którzy worda uznają najlepsze narzędzie do wszystkiego. I tak pisząc wpadłem w pętlę zastanawiania się, jak ja to właściciwe chce napisać.

Od razu na starcie wytłumaczę, że rozumiem, że DDD i Rest to dwa odrębne, niezwiązane ze sobą pojęcia. Ale jednak... ostatnio trochę uległem modzie Domejn Driven Dizajn i dość szybko zaczęło mnie to męczyć - do małej aplikacji wydaje się być przerostem formy nad treścią. Postanowiłem więc olać DDD i doszedłem do wniosku, że w sumie to nie wiem, jakie są inne, dobre alternatywy. Przeglądając różne tutoriale nie doszedłem do żadnych mądrych wniosków - jest albo DDD, albo mapowanie prosto z DTOsa na encje.

Chodzi mi o konkrety. Powiedzmy, że postuję jakąś rezerwację z fronta, controller mapuje sobie DTOsa... i tu pytanie - na co? Czasami chciałbym przed zapisem czy updatem do bazy zrobić kilka walidacji, policzyć jakieś koszty, wysłać jakieś powiadomienia, coś tam wygenerować itp, itd., a czasami po prostu zapisać "as is". Jak robicie takie rzeczy? Jakieś dodatkowe mapowanie / model pomiędzy controllerami a modelem bazy? Czy może operować bezpośrednio na encjach?

6

Jak mała aplikacja, to olej DDD i napisz sobie klasycznie logikę w serwisie. W DDD też są serwisy, a nawet 2 rodzaje. Jak będzie rosło, to sobie zrefaktoryzujesz. Nie zrob tylko syfu pod tytułem kontroler zwraca i przyjmuje encje.

Jeśli interesuje Cię tematyka DDD, to na start proponuje „DDD quickly” i Verhnona. Doczytaj tez o hexagonal architecture, która super się łączy z taktycznym DDD.

1
invisus napisał(a):

Jak robicie takie rzeczy? Jakieś dodatkowe mapowanie / model pomiędzy controllerami a modelem bazy? Czy może operować bezpośrednio na encjach?

  1. Controller przyjmuje DTO
  2. Controller ma w sobie mappera DTO -> encja biznesowa
  3. Controller woła serwis na encji biznesowej
  4. Serwis robi swoje (do persystencji w bazie, można mapować jeszcze na osobną encję JPA (wówczas tylko ona ma adnotacje JPA, a encja biznesowa nie), ale często po prostu encja biznesowa = encja JPA)
  5. Serwis zwraca (jeśli w ogóle cokolwiek) encję biznesową
  6. Mapper zamienia zwróconą encję biznesową w DTO (jeśli serwis ją zwrócił w ogóle)
  7. Controller zwraca jako response body DTO

Oczywiście DTO z punktów 2) i 6) najczęściej są różne

6

Istnieją alternatywy dla DDD które nie są overkillem a nie polegają na encja na twarz i pchasz.
Jest kilka rzeczy które można robić w jakichkolwiek aplikacjach z logiką biznesową.
1)Na poziomie logiki biznesowej nie operujesz encjami z bazy danych ani DTOSami tylko obiektami domenowymi i Value Objectami. Zamiast wykorzystywać BigDecimal amount możesz stworzyć wrapera na niego o nazwie Amount który będzie pilnował poprawności kwoty (tylko 2 liczby po przecinku).
2)Nie używać super serwisów z 10 metodami typu ReservationService tylko operować na UseCase'ach, np. CreateReservationUseCase, CancelReservationUseCase itp
3)Reposytoria powinny zwracać i przyjmować obiekty domenowe i Value Objecty. Tłumaczenie OD/VO <-> encja bazodanowa/JSON z klienta restowego etc powinno odbywać się w warstwie repo.
4)Powinieneń polegać nie niemutowalności.
5)I unikać stosowania wyjątków w sytucjach nie wyjątkowych. Zamiast rzucać ReservationNotFound zwracać pustego Optionala.

1

Tutaj mam projekt o którym pisałem. Pewnie się nie kompiluje, odechciało mi się tego pisać... Bardziej mi chodziło o "zaznajomienie" się z tego typu architekturą.
Cały moduł "application" w zasadzie jest do poprawy. Zależy jakbym finalnie podszedł do "infrastructure". No ale załozenia chyba są spełnione.
https://github.com/Korges/ddd

0
Charles_Ray napisał(a):

Jak mała aplikacja, to olej DDD i napisz sobie klasycznie logikę w serwisie. W DDD też są serwisy, a nawet 2 rodzaje. Jak będzie rosło, to sobie zrefaktoryzujesz. Nie zrob tylko syfu pod tytułem kontroler zwraca i przyjmuje encje.

Jeśli interesuje Cię tematyka DDD, to na start proponuje „DDD quickly” i Verhnona. Doczytaj tez o hexagonal architecture, która super się łączy z taktycznym DDD.

Po części znam już temat, ale poczytam w wolnej chwili, dzięki ;)

Ostatecznie poszedłem na kompromis - prosty Read / Write robię w prosto, w serwisach, a te bardziej złożone rzeczy pcham przez domenę. Jak się rozrośnie to najwyżej domena się rozrośnie ;)

1

Ja mniej więcej strukturyzuję to w podobny sposób jak opisany tutaj, z pewnymi modyfikacjami.

screenshot-20201002102742.png

screenshot-20201002102800.png

0

Tutaj też jest to dość nieźle opisane, troszeczkę bardziej podobne do tego co sam robie niż powyższe

https://allegro.tech/2020/05/hexagonal-architecture-by-example.html
https://github.com/dziadeusz/hexagonal-architecture-by-example

1
invisus napisał(a):

Postanowiłem więc olać DDD i doszedłem do wniosku, że w sumie to nie wiem, jakie są inne, dobre alternatywy. Przeglądając różne tutoriale nie doszedłem do żadnych mądrych wniosków - jest albo DDD, albo mapowanie prosto z DTOsa na encje.

Wydaje mi się, że jak na system rezerwacji ( nie napisałeś czego ) to trochę przestrzeliłeś z doborem sposobu projektowania.
Po prostu zastosuj starą sprawdzoną technologię trójwarstwową. Zaprojektuj bazę w ERD, wymaluj diagramy klas, przepływu danych i stanów i będzie dobrze.

Moim zdaniem stosowanie DDD w małych projektach mija się całkowicie z sensem bo można to ogarnąć o wiele przyjaźniejszymi narzędziami / metodologiami.
To kolejne "modne pojęcie" za którym idzie cała fala nadużyć wynikających z jego błędnego zrozumienia.
W programowaniu małych rzeczy to takie koszenie kombajnem trawnika na działce 400m^2.

1
katakrowa napisał(a):

Wydaje mi się, że jak na system rezerwacji ( nie napisałeś czego ) to trochę przestrzeliłeś z doborem sposobu projektowania.
Po prostu zastosuj starą sprawdzoną technologię trójwarstwową. Zaprojektuj bazę w ERD, wymaluj diagramy klas, przepływu danych i stanów i będzie dobrze.

Moim zdaniem stosowanie DDD w małych projektach mija się całkowicie z sensem bo można to ogarnąć o wiele przyjaźniejszymi narzędziami / metodologiami.
To kolejne "modne pojęcie" za którym idzie cała fala nadużyć wynikających z jego błędnego zrozumienia.
W programowaniu małych rzeczy to takie koszenie kombajnem trawnika na działce 400m^2.

Zgodziłbym się poza strukturą trójwarstwową. Zamiast tego trzymać się package per feature i tyle - a w przypadku małej domeny wszystko w jednym pakiecie i tylko jakieś publiczne api do tego.
DDD jest do skomplikowanych domen ale nie ma potrzeby stosowania struktury trójwarstowej bo ona nie ma w ogóle sensu, jest nieprzenaszalna i nie pozwala traktować modułu/pakietu jako jeden unit.

1 użytkowników online, w tym zalogowanych: 0, gości: 1