Обработка ошибок в REST API: лучшая практика

#spring #rest #spring-boot #spring-rest

#spring #rest #spring-загрузка #spring-rest

Вопрос:

Я пытаюсь разработать rest api, который в основном возвращает информацию о стране. Итак, мой URL будет примерно таким

http://myrestservice/country/US

поэтому, когда приходит запрос с действительной страной, моя служба rest подготовит информацию для этой страны и подготовит вызываемый объект countryInfo и вернет это как

 return  ResponseEntity.status(200).body(countryInfo);
  

теперь скажем, что пользователь отправляет запрос как
http://myrestservice/country/XX . В этом случае, поскольку XX не является допустимой страной, я отправил ответ. Я читал в другом месте, и большинство из них объясняют только код состояния. Мой вопрос в том, каков наилучший способ вернуть ошибку.

  1. return ResponseEntity.status(404).body("Invalid Country");
  2. return ResponseEntity.status(404).body(myobject); //здесь MyObject будет null .

  3. Подготовьте класс say MyResponse.java , как показано ниже.

     public class MyResponse {
    
      private String errorCode;
      private String errorDescription;
      private CountryInfo countryInfo 
    
    }
      

И возвращайте этот объект независимо от того, есть ошибка или нет. При наличии ошибки установлено errorCode и errorDescription поле с правильным значением, для которого countryInfo установлено значение null и для которого ошибка не установлена errorCode и errorDescription как пустая и countryInfo с данными.

Какой из приведенных выше вариантов считается стандартным способом обработки ошибки.

Комментарии:

1. Как вы это решили? Мне нравится ваш третий подход.

Ответ №1:

Вы действительно должны вернуть 404, но то, что вы возвращаете в теле, зависит от вас.

Некоторые люди просто возвращают html-ответ с некоторой информацией, доступной для чтения человеком, но если вы хотите, чтобы ваш клиент API получил дополнительную информацию о том, почему произошел 404, вы также можете захотеть вернуть JSON.

Вместо того, чтобы использовать свой собственный формат, вам следует использовать стандартный application/problem json . Это очень простой формат:

https://www.rfc-editor.org/rfc/rfc7807

Комментарии:

1. Если тело моего ответа не всегда согласовано, то на стороне клиента, если они используют что-то вроде ResponseEntity<CountryInfo> responseEntity = restTemplate.exchange(request, responseType); , это не сработает. Я пытаюсь создать rest-сервис, чтобы клиенту приходилось выполнять минимальную работу.

Ответ №2:

Вы могли бы использовать @ControllerAdvice для обработки исключений:

Ваша конечная точка должна идентифицировать ошибку и выдать сообщение об ошибке:

 @RequestMapping("/country/{code}")
public ResponseEntity<Country> findCountry(String code) {
  Country country = this.countryRepository(code);
  if(country == null) throws new IllegalArgumentException("Invalid country code: "   code);
  return  ResponseEntity.status(200).body(country);
}
  

Затем вы создаете класс, который будет обрабатывать исключения ваших конечных точек:

 @ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(value = { IllegalArgumentException.class })
    protected ResponseEntity<Object> handleConflict(RuntimeException ex, WebRequest request) {
        String bodyOfResponse = "This should be application specific";
        return handleExceptionInternal(ex, bodyOfResponse, 
          new HttpHeaders(), HttpStatus.CONFLICT, request);
    }
}
  

Там вы должны определить код состояния, чтобы указать пользователю, какой тип ошибки был сгенерирован, 409, чтобы указать, что произошел конфликт.

Кроме того, там вы можете определить тело, включающее дополнительную информацию, либо строку, либо пользовательский объект, содержащий сообщение об ошибке и описание, которое вы предлагаете клиенту через документацию.

Комментарии:

1. Я хочу создать стандартный формат для ответа, чтобы потребителю моего rest api не нужно было выполнять обработку исключений. Возможно, это не всегда исключение. Если у нас нет записей, мы должны вернуть статус, в котором говорится, что записи не найдены.

Ответ №3:

Вы можете использовать Zalando Problem , библиотеку, которая реализует application / problem json.

https://github.com/zalando/problem

https://thecodingduck.blogspot.com/2023/01/best-practices-for-rest-api-design.html#standard_error