Я работаю над проектом и после споров с людьми на работе более часа. Я решил узнать, что могут сказать люди на стек-обмене.
Мы пишем API для системы, есть запрос, который должен возвращать дерево организации или дерево целей.
Дерево организации - это организация, в которой присутствует пользователь. Другими словами, это дерево должно существовать всегда. В организации дерево цели должно присутствовать всегда. (вот где начался спор). В случае, когда дерево не существует, мой коллега решил, что было бы правильно ответить на ответ с кодом состояния 200. И затем начал просить меня исправить мой код, потому что приложение разваливалось, когда нет дерева.
Я постараюсь пощадить пламя и ярость.
Я предложил поднять ошибку 404, когда нет дерева. По крайней мере, это дало бы мне знать, что что-то не так. При использовании 200 я должен добавить специальную проверку к моему ответу в обратном вызове успеха, чтобы обработать ошибки. Я ожидаю получить объект, но на самом деле я могу получить пустой ответ, потому что ничего не найдено. Звучит совершенно справедливо, если мы отмечаем ответ 404. И затем началась война, и я получил сообщение, что не понимаю схему кода состояния HTTP. Вот я и спрашиваю, что не так с 404 в этом случае? Я даже получил аргумент «Ничего не нашел , поэтому правильно вернуть 200». Я считаю, что это неправильно, поскольку дерево должно присутствовать всегда. Если мы ничего не нашли и ожидаем чего-то, это должен быть 404.
Больше информации,
Я забыл добавить выбранные URL-адреса.
организации
/OrgTree/Get
цели
/GoalTree/GetByDate?versionDate=...
/GoalTree/GetById?versionId=...
Моя ошибка, оба параметра обязательны. Если предоставляется какая-либо версия versionDate, которую можно проанализировать на определенную дату, она вернет закрытую ревизию. Если вы введете что-то в прошлом, он вернет первую ревизию. Если по идентификатору с идентификатором, который не существует, я подозреваю, что он вернет пустой ответ с 200.
дополнительный
Кроме того, я считаю, что лучшим ответом на проблему является создание объектов по умолчанию при создании организаций, поскольку отсутствие дерева не должно быть допустимым случаем и должно рассматриваться как неопределенное поведение. Невозможно использовать учетную запись без обоих деревьев. По этим причинам они должны присутствовать всегда.
также я связал это (один подобный, но я не могу найти это)
http://viswaug.files.wordpress.com/2008/11/http-headers-status1.png
источник
/GoalTree/GetById?versionId=CompletelyInvalidID
вернуться? Не удалось, так как названный ресурс/GoalTree/GetById?versionId=CompletelyInvalidID
был буквально не найден.Ответы:
В случае сомнений обратитесь к документации . Просмотр определений W3C для кодов состояния HTTP дает нам следующее:
В контексте вашего API это очень сильно зависит от того, как создаются запросы и как извлекаются объекты. Но моя интерпретация всегда была такой:
200
код возврата , если он не существует, возвращает правильный404
код.200
кодом. Основанием для этого является то, что запрос был действительным, он успешно выполнен, и запрос ничего не возвратил.Таким образом, в этом случае вы правы , служба не ищет «конкретную вещь», она запрашивает определенную вещь, если эта вещь не найдена, скажите это ясно.
Я думаю, что Википедия говорит об этом лучше всего:
Кажется, довольно ясно для меня.
По поводу примеров запросов
Вы сказали, что для формата вы всегда возвращаете ближайшую редакцию к этой дате. Он никогда не вернет объект, поэтому он всегда должен возвращаться
200 OK
. Даже если бы это было в состоянии принять диапазон дат, и логика заключалась в том, чтобы вернуть все объекты в течение этого периода, возвращая 200 ОК - 0 Результаты в порядке, так как именно для этого был запрос - набор вещей, которые удовлетворяли этим критериям.Однако последний отличается тем, что вы запрашиваете конкретный объект , предположительно уникальный, с этой идентичностью. Возвращение
200 OK
в этом случае неверно, так как запрошенный ресурс не существует и не найден .Относительно выбора кодов статуса
Вы упомянули в комментарии, используя код 5xx, но ваша система работает. Был задан запрос, который не работает и должен сообщить об этом UA. Независимо от того, как вы это нарезаете, это территория 4хх.
Рассмотрим инопланетянина, опрашивающего нашу солнечную систему
источник
Игнорируя тот факт, что / GoalTree / Get * выглядит как глагол, а не ресурсы, вы всегда должны возвращать 200, потому что URI / GoalTree / Get * представляют ресурсы, которые всегда доступны для доступа, и это не ошибка клиента, если в результате нет дерева запрос. Просто верните 200 с пустым набором, когда нет сущности, которую нужно вернуть.
Вы используете 404, если ресурс не найден, а не когда нет объекта.
Иными словами, если вы хотите вернуть 404 для ваших объектов, то присвойте им свои собственные URI.
источник
/GoalTree/GetById?versionId=12345
это очень хороший URI (ну, по крайней мере, относительный), который идентифицирует конкретный ресурс, а именно данные, соответствующие идентификатору версии12345
в системе. Если данных с таким идентификатором не существует, HTTP-ответ 404 является абсолютно подходящим. Конечно, тело ответа должно, в любом случае, содержать правильно отформатированный ответ (например, JSON, если этого ожидают типичные клиенты, запрашивающие такие ресурсы), указывающий конкретную природу и причину ошибки.Это интересный вопрос, потому что все дело в спецификации системы.
Ответ imel96 убедил меня, что 404 не будет правильным ответом, поскольку семейство кодов 4xx в основном предназначено для ошибок пользователя / клиента , а это не так. URL правильно сформирован, и дерево должно быть там; если это не так, система находится в противоречивом состоянии!
Поэтому это ошибка сервера , то есть что-то в семействе 5xx. Возможно, общая внутренняя ошибка сервера 500 или служба 503 недоступна (служба «принеси мне дерево, которое должно быть там»).
источник
Я бы сказал, что код ответа 200 или 404 может быть действительным , в зависимости от того, как вы смотрите на ситуацию.
Дело в том, что коды ответов HTTP определяются в контексте сервера , который может доставлять различные ресурсы на основе их URL. В этом контексте значения
200 OK
и404 Not Found
совершенно недвусмысленны: первый говорит: «вот ресурс, который вы просили», а второй - «извините, у меня нет такого ресурса».Однако в вашей ситуации у вас есть дополнительный прикладной уровень между HTTP-сервером и реальными ресурсами (деревьями), которые запрашиваются. Приложение занимает своего рода промежуточное пространство, которое не очень хорошо рассматривается в спецификации HTTP.
С точки зрения веб - сервер, заявка выглядит вид на как ресурс: это обычно файл на сервере, которые были определены (часть) URL - адрес, так же как и другие ресурсы (например , файлы статические) сервер может служить. С другой стороны, это странный вид ресурса, поскольку он состоит из исполняемого кода, который динамически определяет содержимое и, возможно, даже код состояния ответа, заставляя его вести себя в некотором роде как мини-сервер.
В частности, в вашем примере, веб-сервер может найти приложение очень хорошо, но затем приложение не может найти подресурс (дерево), который был запрошен. Теперь, если вы считаете, что приложение является просто расширением сервера , а подэлемент (дерево) - фактическим ресурсом, тогда уместен ответ 404 : сервер просто делегировал задачу поиска фактического ресурса приложению который, в свою очередь, не смог этого сделать.
С другой стороны, если ваша точка зрения заключается в том, что приложение является запрашиваемым ресурсом , то, очевидно, веб-сервер должен вернуть ответ 200 ; В конце концов, приложение было найдено и выполнено правильно. Очевидно, что в этом случае приложение должно фактически вернуть действительное тело ответа в ожидаемом формате, указывая (используя любой протокол более высокого уровня, который кодирует этот формат), что фактические данные, соответствующие запросу, не были найдены.
Обе эти точки зрения могут иметь смысл. В большинстве случаев , по крайней мере, для приложений, предназначенных для прямого доступа через HTTP с помощью обычного веб-браузера, я бы предпочел первое представление : пользователь, как правило, не заботится о внутренних деталях, таких как разница между сервером и приложением, он просто заботиться о том, есть ли данные, которые они хотели, есть или нет.
Однако в конкретном случае приложения, предназначенного для связи с другими компьютерными программами, использующими настраиваемый высокоуровневый API-протокол и использующий только HTTP в качестве низкоуровневого транспортного уровня , можно привести аргумент в пользу последнего представления : клиенты, взаимодействующие с таким приложением, на уровне HTTP все, что их действительно волнует , это то, удалось ли им успешно связаться с приложением или нет. Все остальное в таких случаях часто более естественно сообщается с использованием протокола более высокого уровня.
В любом случае, независимо от того, какое из представленных выше представлений вы предпочитаете, есть несколько деталей, о которых следует помнить. Одна из них заключается в том, что во многих случаях может быть значимое различие между (по существу) пустым ресурсом и несуществующим .
На уровне HTTP пустой ресурс будет просто указываться кодом ответа 200 и пустым телом ответа, тогда как несуществующий ресурс будет указываться ответом 404 и телом ресурса, объясняющим отсутствие ресурса. В высокоуровневом API-протоколе обычно указывается несуществующий ресурс с помощью ответа об ошибке, содержащего подходящий код / сообщение об ошибке, зависящее от протокола, тогда как пустой ответ будет просто нормальной структурой ответа без элементов данных.
(Обратите внимание, что ресурс не должен быть буквально нулевым байтом длиной, чтобы быть «пустым» в том смысле, который я имею в виду выше. Например, результат поиска без соответствующих элементов будет считаться пустым в широком смысле, как и результат запроса SQL с нет строк или XML-документ, не содержащий фактических данных.)
Кроме того , конечно же , если приложение действительно считает , что запрашиваемая subresource должна быть там, но не может его найти, то третий возможный код ответа существует:
500 Internal Server Error
. Такой ответ имеет смысл, если наличие ресурса является предполагаемой предпосылкой для приложения, так что его отсутствие обязательно указывает на внутреннюю неисправность.Наконец, вы всегда должны помнить закон Постеля :
Если сервер должен реагировать в той или иной ситуации , с 200 или 404 ответ, это не оправдывает вас как клиента Implementor от обработки либо ответа надлежащим образом и способом , который максимизирует надежную совместимость. Конечно, можно утверждать, что означает «подходящая» обработка в различных ситуациях, но обычно она не должна включать сбой или иное «развал».
источник
Как насчет 204 Нет контента? Предполагается, что ваш запрос был успешно обработан, но ничего не возвращается. Это все еще «успех», но позволяет вам увидеть, есть ли у вас результаты, основанные только на коде состояния.
источник
Если URL представляет ресурс, который никогда не существовал, верните 404 Not Found
Если URL представляет ресурс, который является пустым списком, верните пустой список и 200 OK.
Пример:
Если URL представляет ресурс, который раньше существовал, верните 410 Gone.
Относительно диалога Lego Stormtrooper:
источник
Судя по всему, это API для внутреннего использования. Это дает преимущество при использовании любой схемы, которая дает наибольшую выгоду , независимо от того, является ли она индивидуальной (спецификацией) или нет. Это не означает, что вы должны придумывать свои собственные коды состояния, но это нормально - немного «согнуть» правила, если это выгодно.
Я согласен с вашей позицией, что вы должны получить код состояния, который показывает, что что-то пошло не так. В конце концов, для чего нужны коды состояния. Также вы получаете выгоду от библиотек, которые генерируют исключения / и т.д. на код состояния не-200, поэтому вам не нужно явно проверять (или вы можете написать свою собственную обертку, которая делает это).
Я также согласен с точкой зрения Андреса Ф., что 500 подходит, поскольку дерево должно существовать. Однако на практике мне нравится разбивать ошибки сервера на две категории. Что-то неожиданное пошло не так, а то, что я могу практически проверить, пошло не так. Это приводит к следующим кодам состояния,
В вашем конкретном случае вы можете проверить, существует ли дерево на стороне сервера и, если его нет, вернуть 409. Это ожидаемая ошибка (вы знаете, что это может произойти, вы можете проверить ее и т. Д.) , Конфликт 409 - это только мое личное предпочтение, 5хх также может быть уместным, если вы можете сесть и решить это с вашей командой.
Распределение по категориям кодов помогает быстрее определить тип ошибки, но может иметь преимущества помимо организации. Часто с ошибками веб-сайта вы не хотите, чтобы клиент получал неожиданные ошибки, так как это может быть проблемой безопасности и выявлять уязвимости, поэтому вы возвращаете универсальный 500 «Произошла ошибка». и зарегистрируйте полную ошибку на сервере. Но если ожидаемая ошибка возникает как 409, вы знаете, что было бы безопасно показать ошибку клиенту, и вам не нужно оставлять их в неведении относительно того, что произошло. Это только одно практическое использование, которое я могу рассказать, но есть много возможностей.
Это что-то вроде уловки 22, потому что вы публикуете это из-за невозможности договориться со своими коллегами, но, похоже, вы, ребята, больше спорите о семантике и о том, кто политически корректен. На самом деле не имеет значения, кто является более подходящим, если вы можете придумать систему, которая приносит наибольшую пользу компании.
С другой стороны, если это общедоступный API, следующий спецификациям как можно ближе, было бы более важно, чтобы избежать путаницы среди сообщества.
источник
Возьмите тангенциальный удар по этому вопросу: если человек в конечном итоге использует API (через графический интерфейс), я бы предложил сделать все, что облегчает жизнь конечного пользователя. Отсутствие дерева, когда оно должно существовать, является ошибкой «несоответствия модели домена». Системная ошибка - это когда у вас закончилась память или произошел какой-либо другой системный сбой. Поэтому возвращать 5xx неуместно. Как уже упоминалось несколькими людьми выше, 4xx может быть уместным, если само дерево имеет свой собственный URI, что здесь не так. Но вот что 404 говорит клиенту: вы можете пытаться снова и снова, пока не получите что-то обратно. Если вы вернули 200, вы могли бы вернуть достаточное количество диагностических данных обратно пользователю или пользовательскому агенту, чтобы пользовательский агент мог отображать значение, чтобы пользователь прекратил повторные попытки и просто обратился в службу поддержки. С другой стороны, если этот API предназначен только для систем,
источник