Поместить подробное сообщение об ошибке REST в заголовок HTTP Warning, хорошо / плохо?
Мы разрабатываем стандартную службу REST, используя коды состояния HTTP в качестве кода ответа, если что-то пошло не так. (например, неверный ввод пользователя вернет клиенту "400 неверных запросов")
Однако мы посчитали, что более подробное сообщение об ошибке будет полезно для клиента. (например, неверная ошибка ввода из-за того, что X является нераспознанным именем параметра)
Мы бы хотели быть максимально точными со спецификациями HTTP, поэтому после изучения спецификации в RFC2616 мы подумываем поместить подробное сообщение об ошибке в заголовки HTTP, в частности в поле предупреждения заголовка HTTP. В RFC сказано, что:
Поле общего заголовка Warning используется для передачи дополнительной информации о состоянии или преобразовании сообщения, которая может не отражаться в сообщении. Эта информация обычно используется для предупреждения о возможном отсутствии семантической прозрачности от операций кэширования или преобразований, применяемых к телу сущности сообщения.
Кажется, что нет никаких ограничений на использование этого заголовка для других предупреждений (таких как сообщение об ошибке REST), даже тех, которые не связаны с предупреждениями кэша в соответствии с первоначальным намерением этого заголовка. Нам нравится семантика, и мы планировали использовать код предупреждения 299, который, кажется, вполне соответствует требованиям:
299 Разное постоянное предупреждение Текст предупреждения МОЖЕТ содержать произвольную информацию, которая должна быть представлена пользователю или записана в журнал. Система, получающая это предупреждение, НЕ ДОЛЖНА предпринимать никаких автоматических действий.
Итак, учитывая недопустимый случай ошибки ввода, представленный в верхней части этого вопроса, мы думаем поместить наше сообщение об ошибке REST, как в следующем примере:
HTTP/1.1 400 Bad Request
Warning: 299 ServiceName "Invalid input error: X is unrecognized parameter name."
Это хорошая идея / практика? Мы также обнаружили, что некоторые сервисы подробно описывают это сообщение в заголовке X-Warning, но это, кажется, не стандартно. Мы задаемся вопросом, что бы об этом подумала мудрость улья из стека REST stackru. Существует ли также какая-либо лучшая / стандартизированная практика для раздачи подробных сообщений об ошибках в ответах REST?
7 ответов
Почему бы просто не изменить фразу причины? Вот для чего это. Текст "Плохой запрос" используется по умолчанию. Если вы хотите включить больше информации, используйте тело ответа. Спецификация HTTP говорит, что вы ДОЛЖНЫ включать тело ответа с подробной информацией об ошибке.
ОБНОВИТЬ
Основываясь на более позднем прочтении RFC 7231 и связанного с ним материала, представляется, что единственной действительной причиной для изменения фразы причины является локализация текста, а не предоставление более конкретного значения. Извини за это.
Куда бы вы ни отправили свой отзыв, будь то в теле сообщения (содержании) или в заголовке "Предупреждение", будьте осторожны, чтобы не предоставлять какую-либо информацию, которая может быть полезна злоумышленнику, выполняющему тестирование на проникновение в вашу систему.
Иногда меньше информации лучше.
Я за использование заголовков для предупреждения только тогда, когда запрос в целом успешен.
Например, сервис, который получает данные пользователя, но некоторые детали поступают от третьей стороны, которая часто выходит из строя. В нашем случае было бы целесообразно оставить этот раздел пользовательских данных пустым, но показать пользователю предупреждение о том, что некоторые данные отсутствуют.
Таким образом, запрос вернул 200 Success с полезной нагрузкой, которая содержала все, что мы могли извлечь, но затем содержала заголовки с предупреждением, которые описывали ошибку для остальных.
Если это предложение принято, оно представляет альтернативу для отправки подробных сообщений об ошибках. [ http://tools.ietf.org/html/draft-nottingham-http-browser-hints]
Несмотря на то, что это идентификатор, в последнее время он достаточно стабилен, и я не вижу проблем с созданием собственной реализации. (Я сделал.)
Я за общий подход. Мы должны предположить, что клиентский разработчик находится в другой команде, а не в часовом поясе и т. Д. Возможно, даже в другой компании. Бесполезно просто возвращать ответ "нет, это плохой запрос", как клиент может решить проблему.
Итак, философски: расскажите клиенту о том, что он обязан исправить. Ошибки, которые являются чисто областью действия сервера (например, ошибка подключения к базе данных или какая-то логическая проблема), справедливо просто вернуть ошибку 500. И здесь я не стал бы отправлять детали обратно, мы не хотим раскрывать детали нашей внутренней реализации клиенту.
До сих пор я возвращал данные в теле ответа, используя JAX/RS:
return Response.status(400).entity("some message here").build();
Я думаю, что ваше использование заголовков может на самом деле быть более чистым appraoch.
The Warning
HTTP-заголовок , вероятно, устарел в 2022 году из-за отсутствия клиентской поддержки.
(Однако в будущем его всегда можно будет повторно активировать или переназначить, поэтому я бы с осторожностью относился к изменению семантики вне закрытой экосистемы.)
Кажется, существует RFC «Предлагаемый стандарт» со стандартами, специально созданный для такого рода вещей:
Хотя он не обновлялся с начала 2021 года, также обсуждается draft-cedik-http-warning — передача предупреждающей информации в HTTP API .на GitHub
429 Too Many Requests (RFC 6585) Пользователь отправил слишком много запросов за определенный промежуток времени. Предназначен для использования со схемами ограничения скорости.
Поскольку вы разрешаете один запрос в течение жизни, вы реализуете схему ограничения скорости, поэтому это подходящий HTTP-ответ.
Вы также можете (и это поощряется спецификацией HTTP) настроить тело ответа HTTP, чтобы вы могли изменить "Слишком много запросов" на любое объяснение, которое вы хотите.