В начале этой недели моя команда обсуждала, должны ли HTTP-коды представлять ошибки бизнеса.
Представьте себе сценарий, в котором у нас есть Customer
REST API. В этом API у нас много операций, таких как:
- POST -
mydomain.com/customers
(получить тело JSON и создать нового клиента)
- GET -
mydomain.com/customers/{id}
(поиск конкретного клиента)
- PATCH -
mydomain.com/customers/{id}
(получите тело JSON и исправьте конкретного клиента)
- УДАЛИТЬ -
mydomain.com;customers/{id}
(удаляет определенного Клиента)
А теперь представьте ситуацию, в которой я ищу Customer
с id = 5
.
Там нет Customer
с id = 5
. Что я должен сделать с точки зрения кода состояния HTTP?
Клиент не найден - бизнес-провал. Должен ли я вернуть 404 - НЕ НАЙДЕН ? Должен ли я вернуть 200 - ОК (с текстом JSON, в котором указано, что Клиент с идентификатором 5 не существует)?
Мы обсуждали именно это поведение.
Controller.java (пример)
@GetMapping("/customers/{id}")
public ResponseEntity<?> handleRequestOfRetrieveCustomerById(@PathVariable("id") Integer id) throws CustomerNotFoundException {
try {
ResponseEntity.ok(customerService.findCustomerById(id));
} catch(CustomerNotFoundException e) {
// log at Controller level and rethrow
throw e;
}
}
Handler.java (пример)
@ExceptionHandler(BusinessResourceNotFoundException.class)
@ResponseBody
protected ResponseEntity<Fault> handleExceptionOfBusinessResourceNotFound(BusinessResourceNotFoundException exception) {
return new ResponseEntity<Fault>(exception.getFault(), HttpStatus.NOT_FOUND);
}
В этом примере 404 - НЕ НАЙДЕН возвращается с телом, дающим больше деталей клиенту.
Из чтения спецификации HTTP / 1.1 :
404 Не найдено
Сервер не нашел ничего, соответствующего Request-URI. Нет
указывается, является ли условие временным или
постоянны. Код состояния 410 (Gone) ДОЛЖЕН использоваться, если сервер
через некоторый внутренне настраиваемый механизм знает, что старый
ресурс постоянно недоступен и не имеет адреса пересылки.
Этот код состояния обычно используется, когда сервер не желает
точно указать, почему запрос был отклонен, или когда нет других
ответ применим.
Если «Сервер не нашел ничего, совпадающего с URI запроса ...», я понимаю, что возвращение 404 - НЕ НАЙДЕНО будет правильным подходом, поскольку / id составляет мой URI (mydomain.com/customers/id)
Я прав?
Какой подход лучше / правильнее (если есть неправильный путь)?