Сегодня мы обсуждали операцию передачи, приводящую к код состояния 200, ОК. Было возвращено два объекта, выглядящих вот так.
Первый довольно понятен (и следует ожидаемому контракту).
{ name: "john", age: 34, city: "stockholm" }
Второй - по контракту, но с заведомо неверными данными.
{ name: null, age: -3.141526, city: "http://some.com/address/poof" }
Одна сторона заявила, что код состояния 200 неверен потому что значения неверны. Другая сторона утверждала, что код состояния описывает операцию как таковую и формат запроса / ответа, который прошел успешно потому что передача согласуется с договором.
Совершенно очевидно, что конечная точка REST получает исключение из источников, из которых она извлекает данные. Итак, первая сторона хотела, чтобы результат был либо 404 Не Найдено, либо 500 внутренняя ошибка. Другая сторона была открыта для него при условии, что структура объекта пуста (полностью нулевые) в первом случае и что она не пытается следовать согласованному формату во втором случае.
Проверяя Камасутра, сказано, что:
The request has succeeded. The information returned with the response is dependent on the method used in the request.
Теперь, технически говоря, мы не можем точно знать, имеет ли запрошенный ресурс имя, может ли он быть запланирован на годы PI и находится в городе, который изменил свое название на URL-адрес. Это на самом деле возможно, хотя маловероятно. Однако я хотел бы увидеть явное указание того, что не входит в код состояния 200.
Вопрос: допустимо ли требовать код состояния 400 или выше, потому что значения кажутся (или даже очевидно) неправильными?

В настоящее время RFC 2616 является полностью не имеющий отношения после того, как он был заменен набором новых RFC, которые вместе определяют протокол HTTP / 1.1:
Для HTTP коды состояния см. RFC 7231. Такой документ определяет, что указывает каждый код статуса. Выберите тот, который лучше всего дает результат попытки понять и удовлетворить запрос.
Этот документ также определяет классы кодов статуса, который помогает определить наиболее подходящий статус для ответа:
The first digit of the status-code defines the class of response. The last two digits do not have any categorization role. There are five values for the first digit:
1xx(Informational): The request was received, continuing process
2xx(Successful): The request was successfully received, understood, and accepted
3xx(Redirection): Further action needs to be taken in order to complete the request
4xx(Client Error): The request contains bad syntax or cannot be fulfilled
5xx(Server Error): The server failed to fulfill an apparently valid request
Просто имейте в виду, что коды состояния HTTP - расширяемый. RFC 7231 не включает коды состояния расширения, определенные в других спецификациях. Полный список кодов состояния поддерживается IANA.
Класс кода состояния 2xx указывает, что запрос был успешно выполнен: получили, понял и принял. Если вы не примете неверные данные, то есть объект, который не может быть обработан сервером, код состояния 200 не подходит для этой ситуации.
Код состояния 422 - это то, что вы ищете: синтаксис полезной нагрузки запроса действителен, но не может быть обработан из-за недопустимых данных. Взглянуть:
11.2. 422 Unprocessable Entity
The
422(Unprocessable Entity) status code means the server understands the content type of the request entity (hence a415(Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a400(Bad Request) status code is inappropriate) but was unable to process the contained instructions. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.
For your situation, just read JSON instead of XML.
422 зарегистрирован в IANA и определен в RFC 4918, документе, который определяет WebDAV, расширение для протокола HTTP.
Михаил Кропат составляет набор диаграмм решений, который помогает определить лучший код состояния для каждой ситуации. Коды состояния сгруппированы в три приблизительные категории:
Начните здесь:
Выбор кодов состояния 2xx и 3xx:
Выбор кодов статуса 4xx:
Выбор кодов статуса 5xx:
Код статуса HTTP @DonkeyBanana направлен на предоставление клиенту результат попытки понять и удовлетворить запрос. Ваш сервер определенно выполняет (или, по крайней мере, должен выполнять) своего рода Проверка для данных, которые он получает от клиента. Если полезные данные запроса содержат недопустимые данные, то объект не может быть обработан, следовательно, запрос не может быть принят. Так что 200 здесь не влезет.
Боюсь, я был неясен. Дай мне попробовать снова. Запрос действителен (просто URL и идентификатор). Сервер получает его и извлекает некоторые данные из других источников, а затем возвращает их клиенту. Теперь, когда другая система, которая предоставляет некоторые данные серверу, крутится вокруг и делает странные вещи, предлагаемые данные оказываются ужасными. Следовательно, данные, возвращаемые клиенту с сервера, ужасны.
Вопрос в том, должно ли сообщение сообщать 200 OK (поскольку результат попытки правильный (хотя данные принадлежат FUBAR, но не из-за проблем во взаимодействии клиент-сервер) или должно быть указано 500 Internal error (но все же возвращать объект с пухлыми данными).
@DonkeyBanana Значит, вы говорите о полезной нагрузке отклик вместо полезной нагрузки запроса? Предполагая, что это запрос GET на возврат представления определенного ресурса, который был найден на сервере с заданным идентификатором, верните 200. Если ресурс с данным идентификатором не существует, вернуть 404. Если запрос не может быть выполнен из-за ошибки сервера, вернуть 500. Выберите код состояния, который лучше всего представляет результат операции.
Верно. Понятно. Итак, в заключение - не имеет смысла получать в полезной нагрузке ответа объект, соответствующий по структуре ожидаемому а также сообщения 404 (или 500, если на то пошло). Верный? Я рассуждаю, как в предоставленных вами графиках (+1 за это) - если он не найден, его нельзя вернуть. Вместо этого мы получаем 404 (= извините, чувак, я не дам вам ничего не сказать) или 500 (= ой, чувак, это больно, ничего не даст). (Мне известно о двойном отрицании - точка 404 и 500 не должны представлять запрошенный объект, верно?)
Спасибо за замечание об актуальности и отличный ответ, который меня очень многому научил. Хотя я уверен, что *качество данных * не является фактором в схеме принятия решений, я нигде не могу найти это явно указано. Означает ли это, что это должно быть выведено из его отсутствия или это открывает окно, чтобы встроить его в ответ? Утверждалось, что 200 ОК может иметь предполагаемое качество данных как выполнимое (если не совсем приемлемое, не говоря уже о правильном). Также утверждалось, что это может иметь другое значение при работе с архитектурой REST.