Co powinien w tym przypadku zwrócić Optional?

0

Hej,

tworzę sobie Restowy backend w Javie i zastanawiam się jak rozwiązać sprawę zwracania obiektu w kontrolerze. Może pokażę to na przykładzie kodu.
Mam kontroler, a w nim metodę, która powinna zwrócić na front obiekt o id podanym w ścieżce URI. Do kontrolera mam wstrzyknięte repozytorium wykorzystujące Spring Data. Wbudowana metoda findById zwraca obiekt typu Optional. No więc mój kontroler wygląda tak:

@GetMapping(path = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<DiskType> getDisk(@PathVariable long id){
        return new ResponseEntity<>(diskTypeRepository.findById(id).orElseGet("????"), new HttpHeaders(), HttpStatus.OK);
    }

I co w takiej sytuacji wrzucić do nawiasu po `orElseGet, jeżeli findById zwróci null? Chyba, że w ogóle zabieram się za to od złej strony? To mój pierwszy serwis Restowy, więc jestem trochę zagubiony i staram się zrobić wszystko tak jak się robić powinno

2

Powinienes wtedy zwracać nic jako odpowiedź i kod 404, czyli wykorzystać czyli w coś ala:

diskTypeRepository.findById(id).map(this::diskToResponseEntity).orElse(new ResponsEntity(HttpStatus.NOT_FOUND));
0
scibi92 napisał(a):

Powinienes wtedy zwracać nic jako odpowiedź i kod 404, czyli wykorzystać czyli w coś ala:

diskTypeRepository.findById(id).map(this::diskToResponseEntity).orElse(new ResponsEntity(HttpStatus.NOT_FOUND));

Nic, czyli po prostu... null?

0

Osobiście użyłbym @ControllerAdvice ale o tym musisz trochę poczytać. Wtedy można by w kontrolerze zawsze zwracać status oczekiwany czyli np. 200 podczas pobrania po id. Logikę typu orElse przeniósłbym do warstwy serwisu, który by zapewnił nie zwrócenie null

0
victordeleco2 napisał(a):

Osobiście użyłbym @ControllerAdvice ale o tym musisz trochę poczytać. Wtedy można by w kontrolerze zawsze zwracać status oczekiwany czyli np. 200 podczas pobrania po id. Logikę typu orElse przeniósłbym do warstwy serwisu, który by zapewnił nie zwrócenie null

Wydzielam zatem to do serwisu. Jednak problem dalej pozostaje, bo orElse musi cos zwrocic w przypadku pustego Optionala. Co wiec zwracac wtedy do kontrolera? Pusty obiekt? Czy cos innego? Najlepiej tak, zeby mogl zareagowac na taka sytuacje np. kodem 404 w ResponseEntity.

0
xxx_xx_x napisał(a):

Dlaczego nie skorzystasz z tego?
https://docs.spring.io/spring[...]y.html#of-java.util.Optional-

Skorzystam i przetestuje za chwile, nie skorzystalem wczesniej, bo nie wiedzialem o jej istnieniu. Powinienem chyba czesciej przekopywac dokumentacje, bo rzeczywiscie czesto w banalny sposob mozna dzieki niej rozwiazac swoje problemy

0

Możesz np. stworzyć własny wyjątek DiskNotFoundException a wtedy robisz .orElseThrow(()-> new DiskNotFoundException("Disk with: " + id "not found") i w klasie z @ControllerAdvice to łapiesz i zwracasz 404 a w body np. jego tresc.

1

@Belka: nie słuchaj rad @victordeleco2. Wyjatek nie ma tu żadnego sensu i to bardzo złe rozwiązanie ! Wyjątki sa do sytuacji wyjątkowych (np. błąd odczytu z pliku), ale próba pobrania czegoś co nie istnieje jeśli rzeczywiście może nie istniec to nie jest wyjątkowa sytuacja..

0
scibi92 napisał(a):

@Belka: nie słuchaj rad @victordeleco2. Wyjatek nie ma tu żadnego sensu i to bardzo złe rozwiązanie !

Sprobuje rozwiazania z ResponseEntity.of, bo wyglada ciekawie, a jak juz korzystam z tego Springa to wykorzystam jego mozliwosci. Ciekawi mnie jednak jedna kwestia w Twoim rozwiazaniu.
Zaproponowales tam cos takiego ...diskTypeRepository.findById(id).map(**this::diskToResponseEntity**.....

Rozumiem, ze to mialaby byc funkcja konwertujaca obiekt DiskType na ResponseEntity<disktype> z kodem http 200. Czy taka funkcja powinna byc zaimplementowana w klasie obiektu domenowego (w sensie obiektu @Entity)?

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