Kiedy konwertować na DTO?

Kiedy konwertować na DTO?
PS
PS
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 4 lata
  • Postów:10
0

Hej, mam mikroserwis, który składa się z warstwy kontrolerów, serwisowej, repozytorium (tyle mi wystarcza do spełnienia założeń biznesowych, wiem że jest DDD itd.)

W warstwie kontrolerów mam metodę POST, która przyjmuje JSON'a, następnie w warstwie serwisowej ten Json jest parsowany na obiekt, dokonywane są na nim pewne obliczenia i ten obiekt trafia przez warstwę repozytorium prosto do bazy danych. Czy potrzebuję tutaj używać Mappera?

Flow mojego mikroserwisu przebiega w następujący sposób.

call z rest api do mojego serwisu ---> odebranie jsona w kontrolerze i przekazanie go do warstwy serwisowej ---> parsowanie jsona na obiekt który ma być zapisany w bazie danych w warstwie serwisowej ---> zapisanie obiektu do bazy poprzez warstwę repozytorium.

W jakich przypadkach powinienem używać mapperów do mapowania obiektów wyciąganych z bazy danych i mapowania ich na DTO? Jeżeli mówię o MVC to w której warstwie się to dzieje? Dziękuję za odpowiedź

edytowany 3x, ostatnio: prop_solo
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
2

Generalnie logika powinna się opierać o model domenowy który nie jest modelem bazodanowym i nie powinen mieć żadnych zależności do JPA, Spring Data etc.
Prawdziwie repozytorium w API ma obiekty domenowe np.
Option<Product> findProductById(ProductId productId), gdzie Product to obiekt domenowy. Implementacja repozytorium może wywoływać jakieś niskopoziomowe DAO.
Dodatkowe DTOsy na poziomie API, baz danych, kolejek, websocketów powinno powinny być dodane jeśli sa nietoższame z obiektami domenowymi w 100%, czyli np. mają jakieś adnotacje Jacksona, mają inne pola, etc - czyli w rzeczywistym świecie programowania prawie zawsze :D

W warstwie kontrolerów mam metodę POST, która przyjmuje JSON'a, następnie w warstwie serwisowej ten Json jest parsowany na obiekt

Że co? A jak przekazujesz ten JSON z kontrolerów? Jako String? oO


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
pedegie
  • Rejestracja:około 11 lat
  • Ostatnio:ponad rok
  • Postów:204
3

Jak zadajesz takie pytanie, to prawdopodobnie powinienes zrobic to jakos tak tak:

Kopiuj
@RestController
@RequestMapping(path = "/lessons")
public interface LessonRepository extends JpaRepository<Lesson, Long>
{
    @GetMapping("/field/{name}")
    Page<Lesson> findAllByCourseSpecializationFieldOfStudyName(@PathVariable("name") String name, Pageable pageable);

    @GetMapping
    Page<Lesson> findAll(Pageable pageable);

    @GetMapping("/course/{courseName}")
    Page<Lesson> findAllByCourseName(Pageable pageable, @PathVariable String courseName);

}

Czyli kontroller jest jednoczesnie DAO i serwisem w jednym. Nie ma sensu ani jakis bardziej wyszukany podział ani tym bardziej architektura lazania. Tak w miare szybko mozna naklepac CRUD'a w springu

EDIT: A jak masz obliczenia to wydziel do osobnej klasy dostepem do DAO, ewentualnie jak to jakas drobnica to mozesz rownie dobrze w tym interfejsie zaimplementowac jako default metod, tak naprawde zalezy ile tego (logiki) jest.

edytowany 1x, ostatnio: pedegie
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

Też mam wrażenie ze ty potrzebujesz Spring-Data-Rest jakieś, skoro po prostu robisz RESTową nakładkę na tabele w bazie danych ;)


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
99xmarcin
  • Rejestracja:prawie 5 lat
  • Ostatnio:4 miesiące
  • Postów:2420
1

(tyle mi wystarcza do spełnienia założeń biznesowych, wiem że jest DDD itd.)

Nie trzeba się z tego tłumaczyć. Tysiące aplikacji to CRUDy. Użycie DDD jak piszę się CRUDa to "overengineering", po polsku przekombinowane.

Gdybym to ja był autorem to najprawdopodobniej dokonał bym konwersji JSON <-> DTO już na etapie kontrolera. Dlaczego?

  1. Fail fast - nieprawidłowy JSON nie dotrze nawet do kontrolera. Zamiast tego twój framework zwróci dla użytkownika 4xx.
  2. Jeżeli chciałbyś dodać walidację to możesz użyć JSR 303 (czyli dodać annotację na gettery DTOsa). Z JSONem będzie trudniej.
  3. Security, praktyka znana pod nazwą OVERPOSTING. Jeżeli masz mapowanie map(json, entity) to może się okazać że atakujący doda do JSON pole które nie jest udokumentowane w API ale w encji występuje i zmieni jego wartość.
  4. Elastyczność, zapewne po pewnym czasie nastąpi rozjazd między strukturą danych w DB a tym co jest w JSON'ie. Np. userName w bazie jako ID a w JSON'ie jako email. Mapowanie JSON <-> Entity stanie się coraz bardziej skomplikowane. Będzie łatwiej gdy taka logika mapująca będzie w całości w kodzie.
  5. Co się stanie jak ktoś powie że trzeba też dodać wsparcie dla XMLa? Do DTO można mapować i z JSONa i z XML i z gRPC, ba pewnie GrapahQL też da się zmusić do współpracy.
  6. Twoje API powinno być udokumentowane (np. OpenAPI aka Swagger) Łatwo to zrobić dodając adnotacje na gettery (choć można też użyć plików JSON lub YAML - ale nie polecam bo tooling jest jeszcze niedojrzały).

Generalnie architektura 3-warstwowa opiera się na tym że serwisy zwracają/przyjmują DTO.


Holy sh*t, with every month serenityos.org gets better & better...
edytowany 1x, ostatnio: 99xmarcin
KA
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 2 lata
  • Postów:594
1

IMO praktycznie nigdy nie potrzebujemy wystawiac calej bazy danych a poszczegolne use casy.
Teoretycznie wszedzie powinienes miec jakis obiekt per pakiet i sobie mapowac do niego i na nim operowac i nie mieć brzydkich importow z innych pakietow.
Przy prostych appkach mozna po prostu zrobic sobie funkcje to i from w dto i encjach i uzywac kiedy potrzeba.
I troche na zasadzie Port & Adapters, na wejsciu, wyjsciu z danego pakietu domenowego transformujemy na to co potrzebujemy.
Z tym, że to też moze byc przerost formy nad tresciom jak nam sie kod zamienia w kolko mapowanie z obiektu na obiekt, bo teoretycznie potrzebujemy aż trzech... reprezentacji JSON, Encji bazodanowej i biznesowy obiekt.
Pakiet domenowy = logika biznesowa, brak warstwy infry, czy np. jakis tam controllerow itp.

DDD owszem, ale jego przeznaczenie jest dla skomplikowanych domen biznesowych.

edytowany 3x, ostatnio: karsa
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)