Возврат http 200 OK с ошибкой в ​​теле ответа

Мне интересно, правильно ли возвращать HTTP 200 OK при возникновении ошибки на стороне сервера (подробности ошибки будут содержаться в теле ответа).

Пример:

  1. Мы отправляем HTTP GET
  2. На стороне сервера произошло что-то непредвиденное.
  3. Сервер возвращает HTTP 200 OK код состояния с ошибкой внутри ответа (например, {"status":"some error occurred"})

Это правильное поведение или нет? Должны ли мы изменить код состояния на другое значение, кроме 200?


person krzakov    schedule 13.01.2015    source источник
comment
HTTP 200 означает, что передача разрешена на уровне http. Это не имеет ничего общего с успехом или неудачей вашего бизнес-кода. В этом случае HTTP 200 указывает, что сообщение об ошибке вашего бизнес-кода было успешно передано ;-) В качестве альтернативы вы можете позволить своему серверу ответить HTTP 500, что означает внутреннюю ошибку. Это более типично для технических или неустранимых проблем на сервере.   -  person geert3    schedule 13.01.2015
comment
Кто-нибудь может это подтвердить? Я разговаривал с некоторыми программистами и слышу разные мнения.   -  person krzakov    schedule 13.01.2015
comment
Вместо этого используйте код 412.   -  person Dima Tisnek    schedule 23.11.2017
comment
Глядя на два противоречивых ответа, именно поэтому Stack Overflow должен быть более обнадеживающим для обсуждения.   -  person wobbily_col    schedule 12.04.2018
comment
То, как я это вижу, основано на ожидаемом намерении. Если вызывающий ожидает истинное или ложное, это бизнес-ответ, и истинное и ложное должны быть отправлены обратно в виде 200. С другой стороны, если есть API, который говорит, что обрабатывает удаление заказа - вызов этого API ожидает Порядок уже существует. Если нет, то здесь имеет смысл 404, а не 200. Так что это не один ответ, подходящий для всех ситуаций.   -  person MovieMe    schedule 19.11.2020


Ответы (7)


Нет, это очень неправильно.

HTTP - это протокол приложения. 200 означает, что ответ содержит полезную нагрузку, которая представляет состояние запрошенного ресурса. Сообщение об ошибке обычно не является представлением этого ресурса.

Если что-то пойдет не так при обработке GET, правильный код статуса - 4xx («вы напортачили») или 5xx («я напортачил»).

person Julian Reschke    schedule 13.01.2015
comment
Так в основном вы согласны с предыдущим ответом? - person krzakov; 13.01.2015
comment
Нет, я полностью не согласен с первой частью, которая утверждает, что было бы нормально вернуть 200. - person Julian Reschke; 13.01.2015
comment
Я совершенно запуталась. Два совершенно разных объяснения. - person krzakov; 14.01.2015
comment
Пожалуйста, посмотрите мой комментарий к другому ответу. - person geert3; 14.01.2015
comment
Я думаю, что в некоторых случаях может быть уместна ошибка 200 OK. Но в этом случае клиент делает запрос GET, чтобы некоторые ресурсы не получали этот ресурс, который запрашивал клиент, но получает что-то еще, что неверно. Если это ошибка сервера 5XX, если на стороне клиента 4XX, например, запрашиваемый ресурс не существует 404. Мое мнение. - person FrAn; 14.01.2015
comment
Также обновлен мой ответ, чтобы подробнее рассказать о вариантах использования 200, 4xx и 5xx. - person geert3; 14.01.2015
comment
Но какой код статуса нужно вернуть, если в самолете нет мест? - person Alexanderius; 24.02.2016
comment
В прошлый раз, когда я проверял, самолеты обычно не реализуют HTTP @Alexanderius: P - person vestol; 12.03.2017
comment
Имея недавний опыт работы с очень крупным сайтом электронной коммерции с состоянием 500, я не согласен с этим ответом, подразумевающим не использовать 200 для ошибок. Эта компания, в частности, возвращает все как 200 OK. Все ошибки, которые могут быть обработаны Spring Java, возвращаются как 200, а в теле у вас будет доступное свойство errors. Просто как тот. Не нужно пытаться выяснить, какая ошибка к какому непонятному коду HTTP. - person prograhammer; 21.03.2017
comment
Полностью согласен с этим ответом. В качестве контраста с примерами Google и Facebook в документации по REST API Microsoft Azure они перечисляют несколько ошибок, не имеющих ничего общего с самим уровнем HTTP, которые приводят к ответу 400. docs.microsoft.com/en- us / rest / api / storageservices / - person harperska; 19.05.2017
comment
Когда вы выполняете GET и получаете 200, это означает, что вы можете предположить, что содержимое тела ответа является самим ресурсом, который вы ищете. В вопросе они говорят, что на стороне сервера произошло что-то неожиданное, предположительно это означает, что предполагаемый ресурс не будет возвращен в теле ответа. Это именно тот вариант использования, чтобы вернуть 5xx, точно соответствующий неожиданной ошибке на стороне сервера. - person harperska; 19.05.2017
comment
Кроме того, хотя исходный вопрос касается конкретно GET-запроса, в случае POST-запроса 2xx означает, что вы можете предположить, что ваш ресурс был успешно создан. Ошибки проверки предотвратят это, и поэтому вы должны вернуть 4xx (возможно, 400), указывающее, что ваши POST-данные не прошли проверку. - person harperska; 19.05.2017
comment
HTTP - это протокол приложения. Что ж, хотя wikipedia согласна с этим определением, следует сказать, что здесь application < / b> относится к IP Application Layer, в котором в Википедии перечислены подобные HTTP, Telnet, FTP и SSH - все приложения IP-коммуникаций. Это не то же самое, что и мое приложение / бизнес-логика, в которой используются указанные коммуникации. Таким образом, отправка HTTP 200 с сообщением об ошибке конкретного приложения вполне разумна. - person Jeff Ward; 16.02.2019
comment
Это не учитывает, когда вам нужно действовать над ошибками, не связанными с коммуникациями. I.E: Кредитная карта запрещена XXXX. Для этого нет протокола, поэтому необходимы настраиваемые объекты, которые могут определять действие. - person NSPunk; 12.11.2019

Коды состояния HTTP кое-что говорят о протоколе HTTP. HTTP 200 означает, что передача в порядке на уровне HTTP (т.е. запрос был технически в порядке и сервер смог правильно ответить). См. эту страницу вики для получения списка всех кодов и их значения.

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

В качестве альтернативы вы можете позволить своему серверу ответить HTTP 5xx, если на сервере возникнут технические или неустранимые проблемы. Или HTTP 4xx, если во входящем запросе были проблемы (например, неправильные параметры, неожиданный метод HTTP ...). Опять же, все это указывает на технические ошибки, тогда как HTTP 200 указывает на НЕТ технических ошибок, но не дает никаких гарантий относительно ошибок бизнес-логики.

Подводя итог: ДА, можно отправлять сообщения об ошибках (для нетехнических проблем) в вашем HTTP-ответе вместе с HTTP-статусом 200. Применимо ли это к вашему случаю, решать вам. Если, например, клиент запрашивает файл, которого нет, это больше похоже на 404. Если на сервере есть неправильная конфигурация, это может быть 500. Если клиент запрашивает место в самолете, который забронирован полностью, это будет 200, и ваша реализация будет определять, как распознать / обработать это (например, блок JSON с { "booking": "failed" })

person geert3    schedule 13.01.2015
comment
Видеть. Коды состояния HTTP - это технические ответы, а НЕ ответы бизнес-логики. Я очень хорошо представляю себе HTTP / REST API, в котором HTTP 200 возвращается в случае очевидного сбоя бизнес-логики. Например: я HTTP-клиент, бронирующий рейс на самолет. Все мои параметры в порядке, технически нет причин для HTTP 4xx. Сервер исправен, HTTP 5xx отсутствует. И все же самолет полон. Ответ представляет собой блок JSON, объясняющий этот факт: {"booking":"failed","reason":"plane is full"}. Совершенно нормально для этого получить HTTP 200, на самом деле (ИМХО) это был бы ЕДИНСТВЕННЫЙ действительный код состояния HTTP. - person geert3; 14.01.2015
comment
HTTP 200 не имеет ничего общего с успехом или неудачей вашего бизнес-кода - да, имеет. HTTP - это протокол приложения, это отражают его коды состояния. См. RFC 7231, раздел 6: Элемент кода состояния трехзначный целочисленный код, дающий результат попытки понять и удовлетворить запрос, что означает успешную обработку запроса. Если в какой-либо момент в приложении возникает ошибка (вопрос о том, является ли попытка зарезервировать место на полный рейс ошибкой), вы не должны возвращать код состояния 2xx. - person CodeCaster; 14.01.2015
comment
Взгляните на коды 4xx и 5xx. Они явно предназначены для решения технических вопросов, и понять и удовлетворить запрос следует понимать именно в этом смысле. Сервер не может понять запрос, если он имеет неподдерживаемый тип носителя (415) или метод не разрешен (405). Сервер не может удовлетворить запрос, если превышен предел пропускной способности (509) или истекло время ожидания сетевого чтения (598). Но бронирование места в полном самолете не имеет ничего общего с этими проблемами, и здесь запрос был технически понят и удовлетворен, даже если самолет заполнен, а именно: HTTP 200. - person geert3; 14.01.2015
comment
Чтобы доказать свою точку зрения на практическом примере. REST API Карт Google. developers.google.com/maps/documentation/directions/ Все коды состояния и сообщения об ошибках возвращаются в блоках JSON / XML, но в каждом случае HTTP 200 возвращается на уровне HTTP. - person geert3; 14.01.2015
comment
То, что Google злоупотребляет протоколом HTTP, не означает, что это правильно. Каждый из этих кодов состояния имеет соответствующий HTTP-эквивалент, и только для OK они должны возвращать 200. - person CodeCaster; 14.01.2015
comment
То, что вы противоречите одному из наиболее широко используемых практических API-интерфейсов REST, разработанных крупнейшей интернет-компанией, не делает ваше заявление правильным, я бы сказал наоборот. Опять же: они по праву возвращают HTTP 200, потому что протокол HTTP не дал сбой. Некоторая базовая бизнес-логика не сработала, поэтому они сообщают об этом через XML в ответе HTTP 200. Конечно, некоторые из них могли быть 4хх, но они, вероятно, выбрали в этих случаях согласованность. - person geert3; 14.01.2015
comment
Они возвращают 200 для INVALID_REQUEST (400), OVER_QUERY_LIMIT (429), REQUEST_DENIED (403) и UNKNOWN_ERROR (500). С REST вы используете HTTP как протокол приложения. Спецификации нет, так что все в любом случае нечеткое и основанное на мнениях, но ваши коды состояния HTTP предназначены только для уровня HTTP, слишком жесткие. HTTP позволяет приложениям возвращать коды состояния по своему усмотрению, см. 403 указывает, что сервер понял запрос, но отказывается его авторизовать, 404 указывает, что сервер [..] не желает раскрыть, что он существует. - person CodeCaster; 14.01.2015
comment
@ geert3 у вас есть правильный аргумент, но вы упускаете суть исходного вопроса. Что-то непредвиденное произошло на стороне сервера. Таким образом, правильным ответом будет ответ 5xx. - person radixhound; 14.10.2016
comment
Интересно, что я попытался отредактировать свой комментарий, потому что я случайно отправил его до того, как закончил, и SO ответил 500: «Вы можете редактировать свой комментарий только в течение 5 минут». Таким образом, даже несмотря на то, что моя заявка была «успешной» и ошибка была на моей стороне, она ответила 500. ¯_ (ツ) _ / ¯ Я также хотел поддержать вашу сторону аргумента как действительную, хотя для этого конкретного ответа, вероятно, нет. - person radixhound; 14.10.2016
comment
Facebook Graph API также возвращает 200 OK для всего. - person Sunny; 29.01.2017
comment
Я согласен с этим, кроме 404 NotFound. Это немного сложно при возврате ненайденной ошибки: ответ 404 является правильным, когда клиент запрашивает несуществующий файл, но все ли это правильный способ, когда клиент что-то ищет? (Например, клиент ищет книги с машинным обучением по названию). Должен ли сервер отвечать на ошибку 404 или что-то вроде { "total": 0 }? - person Simon. Li; 12.08.2017
comment
Для меня не имеет смысла возвращать ошибку с 200. Код потребителя будет проверять наличие ошибки в коде состояния. Затем, если ошибка имеет код 200, вам также необходимо проверить содержимое на наличие ошибки. Два чека делают одно и то же. - person wobbily_col; 12.04.2018
comment
@ Simon.Li на самом деле ваш пример возврата HTTP 404 для указания отсутствия совпадений с вашим запросом, на мой взгляд, очень ясный аргумент против использования (технических) кодов ошибок HTTP для проблем бизнес-логики. Тот факт, что книги не были найдены, - проблема бизнеса. Очевидно, страница результатов запроса (хотя и пустая) была найдена, следовательно, HTTP 200. - person geert3; 13.04.2018
comment
@CodeCaster Если нам нужно использовать другой код вместо 200 для примера полной плоскости geert3, какой будет правильный код состояния HTTP вместо 200? - person tonix; 28.06.2018
comment
@tonix - это обсуждение, которое никогда не закончится, потому что нет спецификации, нет правильной. Например, вы можете выступить за конфликт 409. - person CodeCaster; 28.06.2018
comment
@CodeCaster Вы правы, похоже, нет стандартного практического правила. - person tonix; 28.06.2018
comment
Для тех, кто утверждает, что HTTP является протоколом приложения, см. my комментарий выше. Резюме: Уровень приложения IP! = Мое приложение / бизнес-логика. - person Jeff Ward; 16.02.2019
comment
Я считаю, что у обеих сторон этого аргумента есть свои плюсы и минусы. Возможно, золотой серединой было бы возвращение HTTP 200, если все прошло нормально, и общего HTTP 500 с подробностями об ошибках приложения в теле, если что-то пойдет не так? Таким образом, клиент может легко определить, был ли выполнен запрос, путем простой проверки HTTP 200. Если ответ отличается от 200, то клиент может начать изучать детали того, что пошло не так (это 403 или 500 ? Если это 500, какое сообщение об ошибке? И так далее.). Я лично считаю, что таким образом клиентский код становится чище. - person Magnus W; 26.04.2020
comment
Итак, вы говорите, что можно отправить 200, если есть ошибка бизнес-логики, в этом случае мой клиент-потребитель должен будет реализовать каждый блок if-else для обработки ошибок бизнес-логики. Как правило, должно произойти следующее: при возникновении ошибки во время вызова API клиент-потребитель должен обработать ошибку в обработчике ошибок, и вся его логика для обработки ошибок будет отправлена ​​туда. Я предпочитаю возвращать коды ошибок HTTP, если место недоступно, я бы просто вернул 400 с объяснением, чтобы клиент-потребитель мог поймать исключение и отобразить сообщение или, возможно, настроить его. - person Jamshaid K.; 06.04.2021
comment
Тогда как вы можете использовать такую ​​«преднамеренную ошибку», как 401? Все в порядке, но разработчики намеренно блокируют ваш запрос только потому, что не позволяют вам это сделать. С трансмиссией все в порядке. - person legenddaniel; 14.05.2021
comment
Я считаю, что попытки решить, какой код правильный, - пустая трата времени. Поскольку коды используются не всегда, вам не следует ожидать определенного стиля. Скорее сосредоточьте свои усилия на документировании вашего api. - person SILENT; 08.07.2021

Даже если я хочу вернуть ошибку бизнес-логики в виде кода HTTP, для этих ошибок не существует приемлемого кода ошибки HTTP, вместо использования HTTP 200, потому что он искажает фактическую ошибку.

Итак, HTTP 200 подойдет для ошибок бизнес-логики. Но все ошибки, которые покрываются кодами ошибок HTTP, должны использовать их.

По сути, HTTP 200 означает, какой сервер правильно обрабатывает запрос пользователя (в случае отсутствия мест в самолете это не имеет значения, потому что запрос пользователя был правильно обработан, он может даже вернуть только количество мест, доступных в самолете, поэтому будет нет ошибок бизнес-логики вообще или что бизнес-логика может быть на стороне клиента. Ошибка бизнес-логики - это абстрактное значение, но ошибка HTTP более определенная).

person Alexanderius    schedule 12.08.2015

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

Такие ошибки, как недостаточный баланс, недоступны кабины, неверный пользователь / пароль, соответствуют статусу HTTP 200 с обработкой ошибок приложения в теле ответа.

См. этот ответ разработчика программного обеспечения:

Я бы сказал, что лучше четко указать разделение протоколов. Пусть HTTP-сервер и веб-браузер делают свое дело, а приложение - свое. Приложение должно иметь возможность делать запросы, и ему нужны ответы - и его логика относительно того, как запрашивать, как интерпретировать ответы, может быть более (или менее) сложной, чем перспектива HTTP.

person vedant    schedule 11.07.2018
comment
Это может быть вопрос мнения, но я не согласен. Эти ошибки существуют по какой-то причине: нет необходимости изобретать способ отправки стандартной ошибки, просто используйте спецификацию HTTP. Если запрос неверен, отправьте 400, если у пользователя нет доступа к ресурсу, отправьте 403 и т. Д. https://httpstatuses.com/ - person Alexandre Testu; 19.11.2019

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

Плохая практика:

Пример 1:

Darling everything is FINE/OK (HTTP CODE 200) - (Success):
{
  ...but I don't want us to be together anymore!!!... (Error)
  // Then everything isn't OK???
}

Пример 2:

You are the best employee (HTTP CODE 200) - (Success):
{
  ...But we cannot continue your contract!!!... (Error)
  // Then everything isn't OK???
}

Передовой опыт:

 Darling I don't feel good (HTTP CODE 400) - (Error):
{
  ...I no longer feel anything for you, I think the best thing is to separate... (Error)
  // In this case, you are alerting me from the beginning that something is wrong ...
}

Это только мое личное мнение, каждый может реализовать его так, как ему удобнее или нужно.

Примечание. Идея этого объяснения была получена от хорошего друга @diosney

person Jose Carlos Ramos Carmenates    schedule 23.07.2020

Я думаю, что люди придают слишком большое значение логике приложения, а не протоколу. Важно то, что ответ должен иметь смысл. Что делать, если у вас есть API, обслуживающий динамический ресурс, и делается запрос для X, который получен из шаблона Y с данными Z, а Y или Z в настоящее время недоступны? Это ошибка бизнес-логики или техническая ошибка? Правильный ответ: "кого это волнует?"

Ваш API и ваши ответы должны быть понятными и последовательными. Он должен соответствовать какой-то спецификации, и эта спецификация должна определять, что такое действительный ответ. Что-то, что соответствует действительному ответу, должно дать код 200. Что-то, что не соответствует действительному ответу, должно давать код 4xx или 5xx, указывающий на то, почему не может быть сгенерирован действительный ответ.

Если определение допустимого ответа в вашей спецификации допускает { "error": "invalid ID" }, то это успешный ответ. Если ваша спецификация не делает этого приспособления, было бы плохим решением возвращать этот ответ с кодом 200.

Я бы провел аналогию с вызовом функции parseFoo. Что происходит, когда вы звоните parseFoo("invalid data")? Возвращает ли он результат ошибки (возможно, нулевой)? Или возникает исключение? Многие займут почти религиозную позицию относительно правильности того или иного подхода, но в конечном итоге это зависит от спецификации API.

«Элемент status-code - это трехзначный целочисленный код, дающий результат попытки понять и удовлетворить запрос»

Очевидно, есть разногласия относительно того, является ли «успешное возвращение ошибки» успехом или ошибкой HTTP. Я вижу, как разные люди интерпретируют одни и те же характеристики по-разному. Так что выберите сторону, конечно, но также примите тот факт, что в любом случае весь мир не согласится с вами. Мне? Я нахожусь где-то посередине, но предлагаю некоторые соображения здравого смысла.

  1. Если ваш серверный код обнаруживает неожиданное исключение при отправке запроса, это похоже на само определение 500 Internal Server Error. Это похоже на ситуацию OP. Приложение не должно возвращать 200 в случае непредвиденных ошибок, но также см. Пункт 3.
  2. Если ваш серверный код должен уметь корректно обрабатывать данный недопустимый ввод, и он не представляет собой «исключительного» состояния ошибки, ваша спецификация должна учитывать ответы HTTP 200, которые предоставляют значимую диагностическую информацию.
  3. Прежде всего: Имейте спецификацию. Сделайте это последовательным. Придерживайтесь этого.

В ситуации OP похоже, что у вас есть стандарт де-факто, согласно которому необработанные исключения дают 200 с отличимым телом ответа. Это не идеально, но если он не ломает вещи и не вызывает активных проблем, у вас, вероятно, есть более серьезные и важные проблемы, которые нужно решить.

person snarf    schedule 08.08.2019

HTTP - это протокол, обрабатывающий передачу данных через Интернет.

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

Передаваемые данные не обрабатываются кодами ошибок HTTP. Только способ передачи.

HTTP не может сказать: «Хорошо, это чепуха, но вот он». он просто говорит 200 OK.

То есть: я выполнил свою работу по доставке его вам, остальное зависит от вас.

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

person Chris Groves    schedule 10.09.2018
comment
Позвольте мне также сказать, что программисты и разработчики должны правильно сообщать об ошибках на стороне сервера и сообщать пользователю, какая проблема существует на стороне сервера. например, извините, эта страница не работает, или например Я сейчас занят обновлением своей базы данных, скоро буду с вами. - person Chris Groves; 10.09.2018