Walidacja w serwisie, czy objekt o podanym Id istnieje.

0

Mam sobie klasę Movie, która ma właściwość Genre. Gatunki są odgórnie wrzucone do bazy danych ich Id np od 1 do 10, jest możliwość ich dodania lub usunięcia ale operacja będzie, bardzo rzadko wykonywana, bo gatunek nie zmienia się zbyt często. I teraz ktoś chce zaktualizować film i wysyła request z GenreId równym 15. W kontrolerze request przechodzi bo Id > 0 i operacja jest delegowana do serwisu.

  1. Czy w serwisie powinienem od razu nadpisać wartość GenreId i założyć, że klient dokona walidacji zakresu czy najpierw wykonać zapytanie do bazy danych czy istnieje jakiś gatunek o podanym Id?
  2. Gdybym miał takich pól 4 to mam wykonać 4 zapytania do bazy?
  3. Ustawić na sztywno [Range(1, 10)]?
public class Movie
{
	public int GenreId { get; set; }
	public Genre Genre { get; set: }
}
public class UpdateMovieCommand
{
	public int GenreId { get; set; }
}
2

ustaw sobie FK w bazie to przy braku gatunku z danym Id dostaniesz wyjątek, który odeślesz do klienta

0

Pobierz Id wszystkich gatunków jednym zapytaniem i sprawdź czy istnieje.

0

a w "międzyczasie" ktoś jeden usunie i dupa

Czemu miałby to robić ? To pewnie będzie jakiś słownik bazodanowy. Takich rzeczy się nie usuwa od tak. Poza tym to byłby jakiś przypadek brzegowy, który może być chronionym rozwiązaniem, które Ty podałeś. Do tego front też nie powinien pozwolić na wybranie nieistniejącej kategorii.

http://joeduffyblog.com/2014/10/13/if-youre-going-to-fail-do-it-fast/

0

Gatunki są odgórnie wrzucone do bazy danych ich Id np od 1 do 10, jest możliwość ich dodania lub usunięcia ale operacja będzie, bardzo rzadko wykonywana, bo gatunek nie zmienia się zbyt często.

To sugeruje, że może to być rzadkie, ale jednak autor przewiduje możliwość takiego działania. Więc FK wystarczy, a jest to znowu zapytanie per request mniej.

1

napisze inaczej - jeśli jest to projekt na zaliczenie albo do nauki to powinien tam być FK (bo po to one w końcu są aby pilnować spójności danych) i tyle. Jeśli jest to "prawdziwy" projekt to może tam nawet siedzieć student i zatwierdzać każdą transakcję o ile klient będzie za to płacił

1

Przecież dane słownikowe można spokojne wsadzić w cache. Wolę szybko zwalidować input i zwrócić błąd niż wykonać jeszcze potem jakąś logikę i wywalić się dopiero przy zapisie do danych.

0

Domyślnie mam widok z dropdown list, gdzie użytkownik może wybrać gatunek a pod maską binduję Id wybranej opcji, więc jestem na 99% pewny, że będą to poprawne istniejące dane. Ale wystawiając publiczne api nie wiem co otrzymam jako input. Biorąc pod uwagę wasze odpowiedzi mam 3 opcje:

  1. request do bd czy gatunek istnieje, potem kolejny o zapis
  2. request z zapisem i baza danych sprawdza spójność i wali wyjątkiem w razie błędu
  3. trzymanie w cache gatunków, dokonanie walidacji i potem poprawny request

Pierwsza opcja raczej odpada zbyt kosztowna.

error91 napisał(a):

Do tego front też nie powinien pozwolić na wybranie nieistniejącej kategorii.

Myślę, że zastosuję opcję 2 ufając, że front nie pozwoli na złą wartość w razie czego dostaną wyjątek. A w między czasie przetestuję sobie cache i zobaczymy jak to się będzie sprawdzać. Dziękuję za odpowiedzi.

0

Na kliencie masz co masz, i może przyjść stamtąd dosłownie wszystko. Przy pisaniu do bazy jeśli masz poprawnie zdefiniowane relacje serwer bazy danych powinien wywalić wyjątek, czyli w twoim przypadku błąd relacji do tabeli z rekordem z nieistniejącym id. Pozostaje tylko ładnie opakować wyjątek komentarzem i wysłać do klienta.

0

@.Adam: po co próbować zapisywać do bazy dane, co do których jesteśmy pewni, że są nieprawidłowe? Po co tracić czas i zasoby na komunikację z bazą i obsługę wyjątku?

0

@somekind: Nie twierdzę, że za wszelką cenę trzeba zapisywać dane które są na pewno nie poprawne, na pewno trzeba mieć po stronie serwisu logikę która dobrze sprawdzi wszelkie warunki i relacje. Nie można opierać się na tym, że to co idzie z klienta jest ok bo tam ktoś przeprowadził wstępną walidację. Walidacja na kliencie jest ok ale logika pisząca do bazy (serwis) powinna weryfikować ponownie.

0
.Adam napisał(a):

Walidacja na kliencie jest ok ale logika pisząca do bazy (serwis) powinna weryfikować ponownie.

W tym wątku nie ma nic o walidacji klienckiej, tu się toczy dyskusja właśnie o tym, żeby weryfikować w serwisie, a nie walić zbędne zapisy do bazy.
To, że baza zwróci error jeśli naruszymy constrainty to jest oczywistość, i to, że trzeba je obsłużyć również. Ale nie warto czekać na błąd z bazy, skoro można go uniknąć.

0

Zgadza się. Mimo wszystko logikę trzeba zawrzeć w bazie (to absolutne minimum) ale dodatkowo w serwisie. W związku z tym można wygenerować strawny dla użytkownika komunikat. Baza to ostatnia z sciezka obrony ktora musi być. Relacje w .net coś chyba w tym temacie upraszczają. I chyba z takim zamiarem twórcy ich to zrobili.

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