400 против 422 ответа на POST данных

Я пытаюсь выяснить, какой правильный код состояния должен возвращаться в разных сценариях с API-интерфейсом REST, над которым я работаю. Скажем, у меня есть конечная точка, которая позволяет POST-покупки в формате JSON. Это выглядит так:

{
    "account_number": 45645511,
    "upc": "00490000486",
    "price": 1.00,
    "tax": 0.08
}

Что мне следует вернуть, если клиент отправит мне "sales_tax" (вместо ожидаемого "налога"). В настоящее время я возвращаю 400. Но я начал расспрашивать об этом. Должен ли я действительно возвращать 422? Я имею в виду, это JSON (который поддерживается), и он действителен JSON, он просто не содержит всех необходимых полей.

Ответ 1

400 Bad Request теперь будет лучшим протоколом HTTP/1.1 для вашего использования.

Во время вашего вопроса (и моего первоначального ответа) RFC 7231 не было; в какой момент я возражал против 400 Bad Request, потому что RFC 2616 сказал (с акцентом мой):

Запрос не может быть понят сервером из-за неправильного синтаксиса.

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

Однако как отметил Ли Саферет в комментариях, RFC 7231, который устарел RFC 2616, не включает это ограничение:

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


Тем не менее, до этой перезаписи (или если вы хотите, чтобы вопрос о RFC 7231 был только предлагаемым стандартом прямо сейчас), 422 Unprocessable Entity не выглядит неправильным кодом статуса HTTP для вашего потому что как введение в RFC 4918 гласит:

Пока коды состояния, предоставленные HTTP/1.1, достаточны для    описывают большинство условий ошибки, встречающихся с помощью методов WebDAV, там    некоторые ошибки, которые не попадают в существующие категории.    Эта спецификация определяет дополнительные коды состояния, разработанные для WebDAV    методы (раздел 11)

И описание 422 говорит:

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

(Обратите внимание на ссылку на синтаксис, я подозреваю, что 7231 частично устарел 4918)

Это звучит точно так же, как и ваша ситуация, но на всякий случай возникли сомнения: далее

Например, это условие ошибки может возникнуть, если XML    тело запроса содержит хорошо сформированные (то есть синтаксически правильные), но    семантически ошибочные инструкции XML.

(Замените "XML" на "JSON", и я думаю, мы сможем согласиться с вашей ситуацией)

Теперь некоторые будут возражать против того, что RFC 4918 посвящен "HTTP-расширениям для веб-распределенного авторинга и верификации (WebDAV)" и что вы (предположительно) ничего не делаете с использованием WebDAV, поэтому не должны использовать из него что-либо.

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

Кроме того, RFC 4918 Раздел 21.4 относится к IANA Hypertext Transfer Protocol (HTTP) Status Code Registry, где можно найти 422.

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


Но с HTTP/1.1, RFC 7231 имеет тягу, поэтому просто используйте 400 Bad Request!

Ответ 2

Чтобы отразить статус с 2015 года:

Поведенчески как коды ответов 400, так и 422 будут обрабатываться клиентами и посредниками одинаково, поэтому он фактически не дает конкретной разницы, которую вы используете.

Однако я ожидал бы, что 400 в настоящее время используется более широко, и, кроме того, разъяснения, которые предоставляет спецификация HTTPbis, делают его более подходящим для двух кодов состояния:

  • Спецификация HTTPbis уточняет намерение 400 не только для синтаксических ошибок. В настоящее время используется более широкая фраза "указывает, что сервер не может или не обрабатывает запрос из-за чего-то, что воспринимается как ошибка клиента".
  • 422 Является специфическим расширением WebDAV и не упоминается в RFC 2616 или в новой спецификации HTTPbis.

В контексте HTTPbis представляет собой ревизию спецификации HTTP/1.1, которая пытается прояснить области, где это нечеткое или непоследовательное. Как только он достигнет одобренного статуса, он заменит RFC2616.

Ответ 3

400 Bad Request - это правильный код состояния HTTP для вашего прецедента. Код определяется HTTP/0.9-1.1 RFC.

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

http://tools.ietf.org/html/rfc2616#section-10.4.1

422 Unprocessable Entity определяется RFC 4918 - WebDav. Обратите внимание, что есть небольшая разница по сравнению с 400, см. Цитируемый текст ниже.

Это условие ошибки может возникнуть, если тело запроса XML содержит правильно сформированные (т.е. Синтаксически правильные), но семантически ошибочные инструкции XML.

Чтобы поддерживать равномерный интерфейс, вы должны использовать 422 только в случае ответов XML, и вы также должны поддерживать все коды состояния, определенные расширением Webdav, а не только 422.

http://tools.ietf.org/html/rfc4918#page-78

См. Также сообщение Марка Ноттингема о кодах состояния:

его ошибка, чтобы попытаться сопоставить каждую часть вашего приложения "глубоко" с кодами состояния HTTP; в большинстве случаев уровень детализации, на который вы хотите ориентироваться, намного более груб. Если у вас есть сомнения, используйте OK для использования общих кодов состояния 200 OK, 400 Bad Request и 500 Internal Service Error, когда нет лучшей подгонки.

Как думать о кодах статуса HTTP

Ответ 4

Нет правильного ответа, так как это зависит от того, какое определение синтаксиса для вашего запроса. Самое главное, что вы:

  • Использовать код ответа последовательно
  • Включите в тело ответа столько дополнительной информации, сколько сможете, чтобы помочь разработчику (разработчикам), используя ваш API, выяснить, что происходит. =

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

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

Как я сказал выше, решающим фактором является то, что подразумевается под синтаксисом. Если запрос был отправлен с типом контента application/json, то да, запрос синтаксически корректен, поскольку он действителен синтаксисом JSON, но не является семантически корректным, поскольку он не соответствует ожидаемому. (при условии строгого определения того, что делает запрос, о котором идет речь, семантически допустимым или нет).

Если, с другой стороны, запрос был отправлен с более конкретным настраиваемым типом контента типа application/vnd.mycorp.mydatatype+json, который, возможно, точно определяет, какие поля ожидаются, тогда я бы сказал, что запрос может быть легко синтаксически недействительным, следовательно ответ 400.

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

Ответ 5

Во-первых, это очень хороший вопрос.

400 Bad Request - Если из запроса отсутствует критическая часть информации

например. Заголовок заголовка авторизации или заголовка содержимого. Который абсолютно необходим серверу для понимания запроса. Это может отличаться от сервера к серверу.

422 Непроцессная сущность - когда тело запроса не может быть проанализировано.

Это меньше, чем 400. Запрос достиг сервера. Сервер подтвердил, что запрос имеет базовую структуру. Но информация в теле запроса не может быть проанализирована или понята.

например. Content-Type: application/xml, когда тело запроса - JSON.

Здесь приведена статья с кодом состояния и ее использование в API REST. https://metamug.com/article/status-codes-for-rest-api.php

Ответ 6

422 Объяснение необработанной сущности Обновлено: 6 марта 2017 г.

Что такое 422 Unprocessable Entity?

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

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

Дословное определение кода статуса 422, взятого из раздела 11.2 в RFC 4918 можно прочитать ниже.

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

Далее следует определение:

Например, это условие ошибки может возникнуть, если тело запроса XML содержит хорошо сформированные (то есть синтаксически правильные), но семантически ошибочные инструкции XML.

400 против 422 кодов статуса

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

Использование статуса 422 должно быть зарезервировано только для особо случаи использования. В большинстве других случаев, когда произошла ошибка клиента из-за для искаженного синтаксиса следует использовать статус 400 Bad Request.

https://www.keycdn.com/support/422-unprocessable-entity/

Ответ 7

Ваш случай: HTTP 400 - это правильный код состояния для вашего случая с точки зрения REST как его синтаксически неправильный для отправки sales_tax вместо tax, хотя его действительный JSON. Обычно это выполняется большинством фреймворков на стороне сервера при сопоставлении JSON с объектами. Тем не менее, есть некоторые реализации REST, которые игнорируют новый key в объекте JSON. В этом случае пользовательская спецификация content-type для принятия только допустимых полей может быть принудительно реализована на стороне сервера.

Идеальный сценарий для 422:

В идеальном мире 422 является предпочтительным и обычно приемлемым для отправки в качестве ответа, если сервер понимает тип контента объекта запроса и синтаксис объекта запроса является правильным, но не смог обработать данные из-за его семантически ошибочного.

Ситуации 400 по 422:

Помните, что код ответа 422 представляет собой расширенный код состояния HTTP (WebDAV). Есть еще некоторые HTTP-клиенты/интерфейсные библиотеки, которые не готовы обрабатывать 422. Для них это так же просто, как "HTTP 422, это неправильно, потому что это не HTTP". С точки зрения обслуживания 400 не совсем специфичен.

В корпоративной архитектуре службы развертываются в основном на уровне сервисов, таких как SOA, IDM и т.д. Обычно они обслуживают несколько клиентов, начиная от очень старого собственного клиента и заканчивая последними HTTP-клиентами. Если один из клиентов не обрабатывает HTTP 422, параметры заключаются в том, что клиент просит обновить или изменить код ответа на HTTP 400 для всех. По моему опыту, в наши дни это очень редко, но все же возможно. Поэтому перед принятием решения по кодам ответов HTTP всегда требуется тщательное изучение вашей архитектуры.

Чтобы справиться с такой ситуацией, уровни обслуживания обычно используют флаг versioning или setup configuration для строгих клиентов соответствия HTTP для отправки 400 и отправляют 422 для остальных. Таким образом, они обеспечивают обратную совместимость для существующих пользователей, но в то же время обеспечивают возможность для новых клиентов потреблять HTTP 422.


Последнее обновление RFC7321 гласит:

The 400 (Bad Request) status code indicates that the server cannot or
   will not process the request due to something that is perceived to be
   a client error (e.g., malformed request syntax, invalid request
   message framing, or deceptive request routing).

Это подтверждает, что серверы могут отправлять HTTP 400 для недопустимого запроса. 400 больше не ссылается только на синтаксическую ошибку, однако 422 по-прежнему является подлинным ответом, если клиенты могут его обработать.

Ответ 8

Тематическое исследование: API GitHub

https://developer.github.com/v3/#client-errors

Возможно, копирование из известных API - это мудрая идея:

Существует три возможных типа ошибок клиента при вызовах API, которые получают тела запроса:

Отправка недействительного JSON приведет к ответу 400 Bad Request.

HTTP/1.1 400 Bad Request
Content-Length: 35

{"message":"Problems parsing JSON"}

Отправка неправильного значения JSON приведет к ответу 400 Bad Request.

HTTP/1.1 400 Bad Request
Content-Length: 40

{"message":"Body should be a JSON object"}

Отправка недопустимых полей приведет к ответу 422 Unprocessable Entity.

HTTP/1.1 422 Unprocessable Entity
Content-Length: 149

{
  "message": "Validation Failed",
  "errors": [
    {
      "resource": "Issue",
      "field": "title",
      "code": "missing_field"
    }
  ]
}

Ответ 9

Фактически вы должны вернуть "200 OK" , а в теле ответа - сообщение о том, что произошло с опубликованными данными. Затем вы можете обратиться к своему приложению, чтобы понять сообщение.

Дело в том, что коды состояния HTTP - это именно то, что - коды состояния HTTP. И они должны иметь смысл только на транспортном уровне, а не на прикладном уровне. Уровень приложения должен никогда даже не знать, что используется HTTP. Если вы переключили свой транспортный уровень с HTTP на Homing Pigeons, это никак не повлияет на ваш прикладной уровень.

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

  • Ты забыл написать название улицы. Вы получите неоткрытое письмо с сообщением, написанным на нем, в котором говорится, что адрес неверен. Вы не справились с запросом, и почтовое отделение не может его обработать. Это эквивалент получения "400 Bad Request".
  • Итак, вы исправляете адрес и отправляете письмо еще раз. Но из-за какой-то неудачи вы, в общем, ошибочно написали название улицы. Вы снова получите письмо с сообщением о том, что адрес не существует. Это эквивалент получения "404 Not Found".
  • Вы снова исправляете адрес, и на этот раз вам удастся правильно написать адрес. Ваша девушка получает письмо и пишет вам. Это эквивалент получения "200 OK" . Однако это не значит, что вам понравится то, что она написала в своем письме. Это просто означает, что она получила ваше сообщение и ответила за вас. Пока вы не открываете конверт и не читаете ее письмо, вы не можете знать, скучает ли она вам или хочет расстаться с вами.

Вкратце: возврат "200 OK" не означает, что серверное приложение имеет для вас хорошие новости. Это означает только то, что у него есть новости.

PS: Код статуса 422 имеет смысл только в контексте WebDAV. Если вы не работаете с WebDAV, то 422 имеет то же стандартное значение, что и любой другой нестандартный код =, который не является.