Spring boot - Zapisywanie danych POST do kilku tabel

0

Cześć,

Uczę się programowania i wpadłem na pewien pomysł, ale z racji że jestem początkujący to nie wiem czy ma on w ogóle rację bytu.

Chcę zrobić coś takiego, że ze strony frontend'u mam formularz i jak kilkam Submit to wysylam do backendu (w Springu) metodę POST z danymi.
Tylko te dane są podane do dwóch tabel/encji w DB. Odbiorę i zrobię jakiś service springowy, który przetwarza te dane, które dostaję requestem.
W serwisie będzie metoda, która będzie zawierała dwie sqlki (inserty), które będą wpisywać odpowiednie dane do odpowiednich tabel.

To w ogóle jest poprawne i ma ręce i nogi? Czy nie powinno się tak robić?
Jeśli tak, to jaki jest taki normalny/właściwy sposób postępowania w takich przypadkach?

1

Nie jest poprawne bo pisząc ręcznie sql'ki narażasz się na SQL injection.
Skoro masz już springa to zainteresuj się spring data i koncepcja repository.

To à propos tego jak to zrobić lepiej niż zaproponowales.
A czy jest poprawne? Jeśli biznesowo ma to uzasadnienie to spoko ale w komercyjnym projekcie imho należałoby się zastanowić czy taka redundancja danych ma sens.

0

@Batman109:

Batman109 napisał(a):

To w ogóle jest poprawne i ma ręce i nogi? Czy nie powinno się tak robić?
Jeśli tak, to jaki jest taki normalny/właściwy sposób postępowania w takich przypadkach?

Bardzo mi się podoba, że stawiasz sobie to pytanie.

To u czym mówisz, a odniesione do REST, to ja nazywam zgwałcony REST.

Czysty, prawdziwy REST to aktualizowanie stanu obiektów (trudno sobie wyobrazić inaczej niż pojedynczych *) ) za pomocą 3-5 "słów HTTP".
Niestety po kopernikańsku, gorszy pieniądz wypiera lepszy pieniądz, REST uzyskał monokulturową dominację, a w odstawkę poszły modele takie jak RPC, gdzie operacje dało się zamodelować elegancko.

Weźmy takie szkolny przykład, przelew między kontami, w czystym REST to są dwa oddzielne konta, a operacja przelewu miedzy mini nie jest objeta transalcką
patch Http//... accounts/123 ballance=ballance+USD23
patch Http//... accounts/567 ballance=ballane-USD23

Gdzie w RPC byśmy modelowali
moneyTransfer(acc1, acc2, amount)

Na szczęście /nieszczęście przykład przelewu jest na tyle prosty, że wystarczy rest tylko lekko zgwałcony.
post http://..../transfers acc1 =1234, acc2 = 5678, amount = 23
Gwałt niewielki, wprowadźmy fikcyjną encję RESTową o nazwie Przelew/Transfer, która ma powód istnieć tylko chwilkę, aby pod maską zrobić transakcje biznesową (zarazem będącą transakcją bazodanową) przelewu

Więc sam sobie dałem trochę kontrprzykład, ale tylko dlatego ze zjawisko gospodarcze ma bardzo prosty model. Tu obiektu (i endpointu) Transfer(s) da się obronić łatwo, bo jasną nazwę, a i da się uzasadnić jego trwałe istnienie (dla celów ksiegowych / archiwalnych)

Przykład, który wydaje się niewykonalny w czystym REST: zarezerwuj pokoje 17, 19 i 21 (np dla jakiejś grupy przyjaciół, oni znają i lubią te pokoje) - ale wszytskie albo żaden. Na RPC, np względnie najwięcej używam Apache Thrift bym wywołał procedurę makeReservation(roomList, date1, date2)

Wracając do twojego zagadnienia:
O ile grupa modyfikacji bazy danych ma jakiś wyrazisty, elegancki "wspólny mianownik", to są nadzieję na zrobienie, które można uznać za elegancie (i będzie transakcyjne). O ile nie -> też się da, ale to będzie brutalny gwałt na zasadach REST

2

Wspomniałeś, że uczysz się programowania, więc obsłuż sobie tą komunikację z bazą danych za pomocą Spring Data. Będziesz mógł łatwo zdefiniować potrzebne Ci zapytania za pomocą odpowiedniego nazewnictwa funkcji w interfejsach Repository. Dzięki temu będziesz miał więcej czasu, by skoncentrować się na masterowaniu bardziej przydatnych dla Ciebie na tym etapie rzeczy.

1
Belka napisał(a):

Wspomniałeś, że uczysz się programowania, więc obsłuż sobie tą komunikację z bazą danych za pomocą Spring Data. Będziesz mógł łatwo zdefiniować potrzebne Ci zapytania za pomocą odpowiedniego nazewnictwa funkcji w interfejsach Repository. Dzięki temu będziesz miał więcej czasu, by skoncentrować się na masterowaniu bardziej przydatnych dla Ciebie na tym etapie rzeczy.

Ty naprawdę serio?
Tuz obok jest watek, kolega który (w swoich oczach) nie jest początkujący, poległ na czarach Spring Data, zero możliwości własnoręcznie wykaraskania się z błędu. OOooogrooomna warstwa "magii".
Nawet dolna warstwa, JPA/Hibernate, konieczna pod Spring Data, juz jest problemem.

Jak ci @Batman109 sie uda, to bedzisz miał. Jak sie nie uda, nie zdiagnozujesz dlaczego...

Batman109 napisał(a):

W serwisie będzie metoda, która będzie zawierała dwie sqlki (inserty), które będą wpisywać odpowiednie dane do odpowiednich tabel.

Myślenie operacjami SQL nie musi być złe, a nawet dobre, to zależy Ja polecałbym libkę JDBI, ale sa alternatywy

Batman109 napisał(a):

Uczę się programowania i wpadłem na pewien pomysł, ale z racji że jestem początkujący to nie wiem czy ma on w ogóle rację bytu.

Nic o tobie nie wiemy, np czy masz tak głęboko oswojoną Javę, aby sie brać za Springa.
Jeśli nie masz przed oczami za pół roku etatu za 30k, a tylko rzeczywistą naukę, chcesz z http/rest - może projekt Ratpack ?

RequiredNickname napisał(a):

Nie jest poprawne bo pisząc ręcznie sql'ki narażasz się na SQL injection.

NIC w wypowiedzi nie wskazuje na ścieżkę prowadzącą do SQL injection - choć oczywiście tzreba na to uważać.
Nie ma propozycji sklejania stringów SQL, nic takiego nie padło.

0
RequiredNickname napisał(a):

należałoby się zastanowić czy taka redundancja danych ma sens.

Nie ma najmniejszych dowodów na redundancję danych - raczej nieadekwatność tego co mówią ze jest REST-em do rzeczywistości modelu.

0

Miałem zamiar przerobić najprostsza metodę obsługującą POST i zapisującą do tabeli

@PostMapping
    ResponseEntity<?> create(@RequestBody Shows newShows) {
        logger.info("SHOWS: POST METHOD MOVIES");
        logger.info(newShows.getImagePath());
        Shows newMovies = repository.save(newShows);
        return new ResponseEntity<>(newShows, HttpStatus.CREATED);
    }

ewentualnie skorzystać z @Query="Insert into cos tam" i bardziej ręcznie nabazgrać co mi wpisze do odpowiednich tabel

0
Batman109 napisał(a):

Miałem zamiar przerobić najprostsza metodę obsługującą POST i zapisującą do tabeli

@PostMapping
    ResponseEntity<?> create(@RequestBody Shows newShows) {
        logger.info("SHOWS: POST METHOD MOVIES");
        logger.info(newShows.getImagePath());
        Shows newMovies = repository.save(newShows);
        return new ResponseEntity<>(newShows, HttpStatus.CREATED);
    }

ewentualnie skorzystać z @Query="Insert into cos tam" i bardziej ręcznie nabazgrać co mi wpisze do odpowiednich tabel

Jeśli to do mnie pytanie - nie udzielasz objaśnień o projekcie danych, jakie miałbyś insertowane. A to głęboko wpływa na uznanie tego za "całkiem eleganckie" / "może być" / "ledwo się trzyma" / "kiła"
Co to za dane, jaka jest ich spójność biznesowa / relacyjna a bazie danych. Jaki charakter ma CAŁA transakcja (i czy w ogóle nią jest)

4
RequiredNickname napisał(a):

Nie jest poprawne bo pisząc ręcznie sql'ki narażasz się na SQL injection.
Skoro masz już springa to zainteresuj się spring data i koncepcja repository.

Czy ktoś tu odpowiedział już że od tego żeby nie mieć SQL injection jest Prepared Statements ?

1

Może pokaż ten formularz, co on zawiera i na jakie tabele chcesz go rozdzielić.

3

Podejście, w którym pojedyncze żądanie wpływa na więcej niż jedną tabelę jest OK.
POST /contacts

{
  "name":"Jan",
  "lastName":"Kowalski"
  "telephonNumbers":[
    "123456787",
    "87654321"
  ]
}

W bazie danych masz 2 tabele (contact i telephon_numbers) 1-n i dotkniesz 2 tabel wieloma insertami.

0
piotrpo napisał(a):

Podejście, w którym pojedyncze żądanie wpływa na więcej niż jedną tabelę jest OK.
POST /contacts

{
  "name":"Jan",
  "lastName":"Kowalski"
  "telephonNumbers":[
    "123456787",
    "87654321"
  ]
}

W bazie danych masz 2 tabele (contact i telephon_numbers) 1-n i dotkniesz 2 tabel wieloma insertami.

To jest BARDZO DOBRY głos, zarazem ujawnia podstawowy problem tego wątku: myślenie encjami bazodanowymi / tabelami na miejscu wysokopoziomowym, w tym wypadku REST.
Podany przez Ciebie przykład ślicznie pokazuje JEDEN obiekty biznesowy - a co do tego nie ma najmniejszych zarzutów - rozkładający się na wiele tabel (o ile tabele są w RBD, bo w dokumentowej już nie)

Neisiety pytający @Batman109 mimo wezwań ucieka od powiedzenia konkretnie, o jakich danych mowa.

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