Hej, piszę aplikację w której użytkownik będzie mógł się zapisać na spotkania. Najpierw napisałem to z wykorzystaniem wyjątków i wyglądało to mniej więcej tak:
@PostMapping("book")
@PreAuthorize("hasRole('STUDENT')")
public ResponseEntity<?> bookMeeting(Principal principal, @Valid @NotBlank @RequestParam(value="id") Long id)
{
User user = userService.findByUsername(principal.getName());
if(user== null) throw UserNotFoundException("no such user") // to w ogole jest mozliwe?
Meeting meeting = meetingService.findById(id);
if(meeting == null) throw MeetingNotFound
return meetingService.bookMeeting(meeting,user);
}
W meetingService.bookMeeting()
sprawdzałem czy meeting.getUser() == null
(czyli czy spotkanie nie jest już zarezerwowane) i tez rzucałem jakiś wyjątek na koniec jak wszystko było OK to zwracałem jakieś Response
, w wyjątkach miałem jakiś @ResponseStatus
i jak coś poszło nie tak to zwracało jakąś wiadomość.
Po obejrzeniu paru filmików p. Jarka uznałem, że nie ma sensu rzucać wyjątków gdy nie występują jakieś skrajne sytuację.
teraz ciało bookMeeting wyglądałoby tak:
Option<User> user = userService.findByUsername(principal.getName());
Option<Meeting> meeting = meetingService.findById(id);
Either<Error, Meeting> book = meetingService.bookMeeting(meeting,user);
if(book.isRight()) return ResponseEntity.ok(book.getRight());
else return ResponseEntity.badRequest(book.getLeft().getMessage());
więc bookMeeting powinno wyglądać mniej więcej tak:
if(user.empty()) return Either.Left(new Error("no such user"));
if(meeting.empty()) return Either.Left(new Error("no such meeting"));
if(meeting.get().getUser().empty()) return Either.Left(new Error("meeting already booked"));
... jakies operacje typu meeting.setUser(user), zapisz do bazy danych
return Either.Right(...);
Kod wydaję się być minimalnie lepszy pozbyłem się tego skakania do wyjątków ale chyba dalej jest to słabe przez to sprawdzanie czy kontener jest pusty. Próbowałem to napisać z map(), zrobić takie map().map().map()
jak coś poszło nie tak to odpowiedni Error
ale średnio mi to wychodziło, nie wiem jak w środku użyc Meeting::setUser
z argumentem, poprzednio sprawdzając wszystko czy istnieje i jeżeli coś nie istnieje to zwrócic odpowienio Either.Left(Error)
Jak to powinno być napisane, żeby wszystko było ok?
z góry dzięki