Spring REST API jak zwracać błędy

Spring REST API jak zwracać błędy
0

Jak powinno się zwracać błędy w typowym REST API? Problem jest w tym że @Valid sprawdzam dto, a dodatkowo musze sprawdzić np. czy taki user nie istnieje w bazie. Sprawdzam to więc w serwisie. Czyli kontroler wygląda tak:
W serwisie mam metode validateAndRegister. Chciałem żeby przy udanej rejestracji zwróciło HttpStatus.OK i body tego usera. Jak coś jest nie tak to jakiś Bad Request i też w jsonie body błędy. Ale spotkałem się z opinią że słabo wygląda jak serwis jest typu ResponseEntity. Więc co mam zwracać żeby dało się to jakoś połączyć?

Kopiuj
  @PostMapping("/register")
    public ResponseEntity registerNewUser(@ModelAttribute @Valid RegisterDto registerDto, BindingResult result) {
        if (result.hasErrors()){
            return  ResponseEntity.badRequest().body(result);
        }
userService.validateAndRegister(registerDto)
        return ResponseEntity.ok().body();
    }
Bambo
W kontrolerze zwracasz normalnie jakiegoś dtos'a - wstępną walidację możesz zrobić przez adnotacje, a potem w serwisie sprawdzać np. czy user istnieje i rzucać jakieś wyjątki, które przechwytujesz np. w globalnym handlerze błędów, ustawiasz kod odpowiedzi i opakowujesz to w jakiś własny ErrorObject czy coś takiego. I czemu dane do rejestracji przesyłasz przez parametry a nie przez body ?
TJ
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 5 lat
  • Postów:35
0

Ale spotkałem się z opinią że słabo wygląda jak serwis jest typu ResponseEntity.

Sam tak robię, więc się nie wypowiem na temat czy dobrze czy źle...

Nie wiem jak wygląda metoda validateAndRegister() ale po nazwie sadzę, że może być jakaś walidacja, więc proponuje ją rozdzielić na validate i register.
A co do błędu proponuje zrobić sobie metodę pomocniczą zwracającą "ładnie" błąd:

Kopiuj
public Map<String, Object> errorResponseBuilder(BindingResult bindingResult) {
		Map<String, Object> response = new HashMap<String, Object>();
		Map<String, String> errors = new HashMap<String, String>();

		List<FieldError> fieldErrors = bindingResult.getFieldErrors();
		for (FieldError fieldError : fieldErrors) {
			errors.put(fieldError.getField(), fieldError.getDefaultMessage());
		}
		response.put("error", errors);
		return response;
	}

btw zawsze możesz dodać swój błąd do bindingResult poprzez

Kopiuj
bindingResult.addError(new FieldError("objectName", "objectField", "Message"));

i wtedy możesz najpierw sprawdzić czy użytkownik już istnieje i dodać do bindingResult

Kopiuj
        if (result.hasErrors())
return new ResponseEntity<>(errorResponseBuilder(result), HttpStatus.BAD_REQUEST);
else
 return new ResponseEntity<>(userService.validateAndRegister(registerDto), HttpStatus.CREATED);
edytowany 3x, ostatnio: toJaMichal

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.