1. Введение
В этом кратком руководстве мы научимся возвращать ошибки HTTP 4XX в Spring-приложениях.
2. Рекомендуемые HTTP Status Codes в Restful APIs
При проектировании RESTful API мы всегда должны проектировать наши API так, чтобы возвращать клиенту осмысленный HTTP response, чтобы было ясно, каков результат запроса. Для сценариев happy path наиболее простым подходом является возврат ожидаемого ответа. В этом случае spring по умолчанию установит заголовок в HTTP 200. Однако, когда запрос завершается неудачей, нам нужно вернуть клиенту соответствующий HTTP status code. Например, когда клиент отправляет запрос с некорректными данными, мы должны вернуть HTTP 4XX Request status code.
Spring предоставляет несколько способов вернуть соответствующий ответ. Здесь мы рассмотрим класс ResponseEntity.
3. Плохой пример обработки HTTP Errors
Давайте рассмотрим простой пример, в котором у нас есть controller method, возвращающий имя студента как string:
@GetMapping(value = "/student/{id}/name")
@ResponseBody
public String getStudentNameById(@PathVariable String id) {
Optional<Student> student = studentService.findById(matchId);
if(student.isPresent()){
return student.get().getName();
}
// --- What to do here?
}
Выше, если мы находим студента, мы возвращаем его имя; в противном случае нам нужно обработать сценарий «не найдено». Например, мы можем вернуть строку ошибки:
@GetMapping(value = "/student/{id}/name")
@ResponseBody
public String getStudentNameById(@PathVariable String id) {
Optional<Student> student = studentService.findById(matchId);
if(student.isPresent()){
return student.get().getName();
}
return "Student not found";
}
В этом случае controller method возвращает HTTP 200 status code, что может подорвать доверие клиента, поскольку ответ не соответствует их ожиданиям. Вместо этого мы должны вернуть HTTP 404 Not Found status code.
4. Использование ResponseEntity
Чтобы решить эту проблему, мы можем использовать класс ResponseEntity. Обернув возвращаемый тип controller method в ResponseEntity<?>, мы можем задать как HTTP status code, так и response body.
Теперь мы не можем возвращать string напрямую. Вместо этого нам нужно вернуть экземпляр ResponseEntity:
@GetMapping(value = "/student/{id}/name")
public ResponseEntity<?> getStudentNameById(@PathVariable String id) {
Optional<Student> student = studentService.findById(matchId);
if(student.isPresent()){
return ResponseEntity.ok(student.get().getName());
}
return ResponseEntity.notFound().build();
}
Выше мы используем метод ResponseEntity.ok() чтобы вернуть имя студента, если он найден. Если студент не найден, мы возвращаем код состояния HTTP 404 Not Found, используя метод ResponseEntity.notFound().
Начиная с Spring 4.1, класс ResponseEntity предоставляет несколько helper methods для создания экземпляров ResponseEntity с различными HTTP status codes. Это делает наш код более читаемым и выразительным.
Например, чтобы вернуть HTTP 400 Bad Request status code, мы можем использовать метод ResponseEntity.badRequest() или решить построить ответ вручную:
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
5. Преимущества использования ResponseEntity
Использование ResponseEntity<?> в качестве возвращаемого типа для controller methods даёт нам несколько преимуществ:
-Flexibility Это обеспечивает большую гибкость при определении HTTP status code и response body. -Readability Код становится более читаемым и выразительным, особенно при использовании helper methods. -Consistency Это способствует единообразному подходу в нашем приложении к обработке HTTP responses.
6. Заключение
В этой короткой статье мы узнали, как обрабатывать HTTP 4XX errors в приложении Spring, используя ResponseEntity class. Сначала мы объяснили суть проблемы. Затем мы показали важность возвращения правильных HTTP status codes в RESTful APIs. Наконец, мы продемонстрировали пример использования ResponseEntity class с его helper methods.


