HTTP 400 (неверный запрос) для логической ошибки, синтаксис неправильного запроса - PullRequest
63 голосов
/ 24 января 2011

Спецификация HTTP / 1.1 (RFC 2616) имеет следующее значение для значения код состояния 400, Плохой запрос (§10.4.1) :

Сервер не смог понять запрос из-за неправильного синтаксиса.Клиенту НЕ СЛЕДУЕТ повторять запрос без изменений.

В настоящее время среди немногих API на основе HTTP существует общепринятая практика использовать 400 для обозначения логического вместо синтаксис ошибка с запросом.Я предполагаю, что API делают это, чтобы различать 400 (клиентский) и 500 (серверный).Допустимо или неправильно использовать 400 для обозначения несинтаксических ошибок?Если это приемлемо, есть ли аннотированная ссылка на RFC 2616, которая дает более полное представление о предполагаемом использовании 400?

Примеры:

Ответы [ 7 ]

62 голосов
/ 24 января 2011

Статус 422 ( RFC 4918, раздел 11.2 ) приходит на ум:

Код состояния 422 (Unprocessable Entity) означает, что сервер понимает тип содержимого объекта запроса (следовательно, код состояния 415 (Unsupported Media Type) не подходит), и синтаксис объекта запроса является правильным (таким образом, 400 (Неверный запрос) код состояния не подходит), но не удалось обработать содержащиеся в нем инструкции. Например, это условие ошибки может возникать, если тело запроса XML содержит правильно сформированные (то есть синтаксически правильные), но семантически ошибочные инструкции XML.

15 голосов
/ 25 июня 2013

На данный момент в последней версии спецификации HTTPbis , которая предназначена для замены и устаревания RFC 2616, говорится :

Код состояния 400 (неверный запрос) указывает, что сервер не может или не будет обрабатывать запрос, поскольку полученный синтаксис является недопустимым, бессмысленным или превышает некоторые ограничения в отношении того, что сервер готов обработать.Это определение, хотя, конечно, все еще подвержено изменениям, подтверждает широко используемую практику реагирования на логические ошибки с 400.

6 голосов
/ 15 октября 2012

HTTPbis будет обрабатывать фразу 400 Bad Request, чтобы она также охватывала логические ошибки. Таким образом, 400 будут включать 422.

С https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-18#section-7.4.1
«Сервер не может или не будет обрабатывать запрос из-за ошибки клиента (например, неправильный синтаксис)»

2 голосов
/ 24 января 2011

Несмотря на то, что я использовал 400 также для представления логических ошибок, я должен сказать, что возвращение 400 в данном случае неверно из-за способа чтения спецификации. Вот почему я так думаю, что логическая ошибка может заключаться в том, что отношения с другим объектом нарушаются или не удовлетворяются, и внесение изменений в другой объект может привести к тому, что то же самое пройдет позже. Например, попытка (совершенно гипотетически) добавить сотрудника в качестве члена отдела, когда такого сотрудника не существует (логическая ошибка). Добавление сотрудника в качестве запроса участника может быть неудачным, поскольку сотрудник не существует. Но тот же самый точный запрос может пройти после добавления сотрудника в систему.

Только мои 2 цента ... Нам нужны юристы и судьи, чтобы интерпретировать язык в RFC:)

Спасибо, Вишь

2 голосов
/ 24 января 2011

Можно утверждать, что наличие неверных данных в вашем запросе является синтаксической ошибкой, даже если ваш фактический запрос на уровне HTTP (строка запроса, заголовки и т. Д.) Синтаксически действителен.

Например, если веб-служба Restful задокументирована как принимающая POST с пользовательским типом содержимого XML application/vnd.example.com.widget+xml, и вы вместо этого отправляете какой-то бредовый текст или двоичный файл, кажется разумным рассматривать это как синтаксическую ошибку - вашТело запроса не в ожидаемой форме.

Я не знаю ни одного официального упоминания, подтверждающего это, хотя, как обычно, кажется, что до интерпретации RFC 2616, как обычно, нет.

Обновление: Обратите внимание на пересмотренную формулировку в RFC 7231 §6.5.1 :

Код состояния 400 (неверный запрос) указывает, что сервер не может или не будет обрабатыватьзапрос из-за чего-то, что воспринимается как ошибка клиента, например, синтаксис неверно сформированного запроса, неверное формирование кадра запроса или обманчивая маршрутизация запроса).

см.мс, чтобы поддержать этот аргумент больше, чем устаревший RFC 2616 §10.4.1 , который просто сказал:

Запрос не может быть понят сервером из-за неправильного синтаксиса.Клиент НЕ ДОЛЖЕН повторять запрос без изменений.

1 голос
/ 23 января 2019

Это сложно.

Я думаю, что мы должны;

  1. Вернуть ошибки 4xx только в том случае, если у клиента есть возможность внести изменения в запрос, заголовки или тело, что приведет к успешному выполнению запроса с тем же намерением.

  2. Вернуть коды диапазона ошибок, если ожидаемая мутация не произошла, т.е. УДАЛЕНИЕ не произошло или PUT ничего не изменило. Однако POST более интересен, потому что спецификация говорит, что его следует использовать для создания ресурсов в новом месте или просто для обработки полезной нагрузки.

Если использовать пример из ответа Виша, если в запросе предполагается добавить сотрудника Прия в отдел маркетинга, но Прия не была найдена или ее учетная запись заархивирована, то это ошибка приложения.

Запрос работал нормально, он попал в правила вашего приложения, клиент все сделал правильно, ETag-файлы совпали и т. Д. И т. Д.

Поскольку мы используем HTTP, мы должны отвечать на основании влияния запроса на состояние ресурса. И это зависит от вашего дизайна API.

Возможно, вы разработали это.

PUT { updated members list } /marketing/members

Возвращение кода успеха будет означать, что «замена» ресурса сработала; GET на ресурсе будет отражать ваши изменения, но не будет.

Так что теперь вам нужно выбрать подходящий отрицательный код HTTP, и это сложная часть, поскольку коды строго предназначены для протокола HTTP, а не для вашего приложения.

Когда я читаю официальные коды HTTP, эти два выглядят подходящими.

Код состояния 409 (Конфликт) указывает, что запрос не может быть выполнен из-за конфликта с текущим состоянием целевого ресурса. Этот код используется в ситуациях, когда пользователь может разрешить конфликт и повторно отправить запрос. Сервер ДОЛЖЕН генерировать полезную нагрузку, которая включает в себя достаточно информации, чтобы пользователь мог распознать источник конфликта.

И

Код состояния 500 (Внутренняя ошибка сервера) указывает, что сервер обнаружил непредвиденное состояние, которое не позволило ему выполнить запрос.

Хотя мы традиционно считали, что 500 - это необработанное исключение: - /

Я не считаю неразумным придумывать собственный код состояния, если он последовательно применяется и разрабатывается.

С этим дизайном легче иметь дело.

PUT { membership add command } /accounts/groups/memberships/instructions/1739119

Затем вы можете создать свой API-интерфейс, чтобы всегда успешно создавать инструкцию, он возвращает 201 Created и Location header, и любые проблемы с инструкцией сохраняются в этом новом ресурсе.

POST больше похож на последний PUT в новом месте. POST позволяет обрабатывать сообщения любого типа на сервере, что открывает проекты, которые говорят что-то вроде «Действие успешно завершилось неудачей».

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

При наличии POST вы возвращаете 200 или 201 вместе с сообщением об отказе, зависит от того, был ли создан новый ресурс и доступен ли GET в другом месте или нет.

С учетом всего вышесказанного, я был бы склонен разрабатывать API, которым требуется меньше PUT, возможно, просто обновлять поля данных, а действия и вещи, которые вызывают правила и обработку или просто имеют более высокий шанс ожидаемых сбоев, могут быть разработаны для ПОСТА форма инструкции.

1 голос
/ 30 августа 2013

На серверах Java EE возвращается 400, если ваш URL ссылается на несуществующее «веб-приложение». Это «синтаксическая ошибка»? Зависит от того, что вы подразумеваете под синтаксической ошибкой. Я бы сказал, да.

В английском языке синтаксические правила предписывают определенные отношения между частями речи. Например, «Боб женится на Мэри» синтаксически правильно, потому что он следует шаблону {существительное + глагол + существительное}. В то время как «Боб-брак Мэри» будет синтаксически неправильным, {имя существительное + существительное + существительное}.

Синтаксис простого URL - {протокол +: + // + сервер +: + порт}. В соответствии с этим "http://www.google.com:80" является синтаксически правильным.

А как насчет "abc: //www.google.com: 80"? Похоже, по той же схеме. Но действительно это синтаксическая ошибка. Зачем? Потому что 'abc' не является ОПРЕДЕЛЕННЫМ протоколом.

Суть в том, что для определения, есть ли у нас ситуация 400, требуется больше, чем анализ символов, пробелов и разделителей. Он также должен распознавать, что является действительными «частями речи».

...