Я строю сервер, который позволяет клиентам хранить объекты. Эти объекты полностью сконструированы на стороне клиента, дополнены идентификаторами объектов, которые являются постоянными в течение всего времени существования объекта.
Я определил API, чтобы клиенты могли создавать или изменять объекты с помощью PUT:
PUT /objects/{id} HTTP/1.1
...
{json representation of the object}
{Id} - это идентификатор объекта, поэтому он является частью Request-URI.
Теперь я также рассматриваю возможность разрешения клиентам создавать объект с помощью POST:
POST /objects/ HTTP/1.1
...
{json representation of the object, including ID}
Поскольку POST подразумевается как операция добавления, я не уверен, что делать, если объект уже существует. Должен ли я рассматривать запрос как запрос на изменение или я должен вернуть код ошибки (который)?
Ответы:
Мое чувство является
409 Conflict
наиболее подходящим, однако, редко встречается в дикой природе, конечно:источник
HTTP 409
сLocation
заголовком, указывающим на существующий / конфликтующий ресурс.В соответствии с RFC 7231 , A 303 See Other МОЖЕТ использоваться Если результат обработки POST будет эквивалентно представлению существующего ресурса .
источник
Лично я иду с расширением WebDAV
422 Unprocessable Entity
.Согласно RFC 4918
источник
422
мне кажется странным ...Все дело в контексте , а также в том, кто отвечает за обработку дубликатов в запросах (сервер или клиент или оба)
Если сервер просто указывает дубликат , посмотрите на 4xx:
Для неявной обработки дубликатов, посмотрите на 2XX:
если сервер должен что-то вернуть , посмотрите на 3XX:
когда сервер может указать существующий ресурс, это подразумевает перенаправление.
Если вышеуказанного недостаточно, всегда рекомендуется подготовить сообщение об ошибке в теле ответа.
источник
Возможно, в конце игры, но я столкнулся с этой проблемой семантики, пытаясь создать REST API.
Чтобы немного расширить ответ Вриккена, я думаю, что вы можете использовать любой из них
409 Conflict
или в403 Forbidden
зависимости от ситуации - вкратце, используйте ошибку 403, когда пользователь не может сделать абсолютно ничего для разрешения конфликта и завершения запроса (например, он не может отправить запрос).DELETE
запросить явное удаление ресурса) или использовать 409, если что-то может быть сделано.В настоящее время кто-то говорит «403», и возникает проблема с разрешениями или аутентификацией, но спецификация говорит, что это в основном сервер, который говорит клиенту, что он не собирается этого делать, не спрашивайте его снова, и вот почему клиент должен «т.
Что касается
PUT
vs.POST
...POST
следует использовать для создания нового экземпляра ресурса, когда пользователь не имеет средств или не должен создавать идентификатор для ресурса.PUT
используется, когда идентификатор ресурса известен.источник
POST
запросом (при правильном использовании), поскольку в нем говорится, что он должен быть возвращен, когда он конфликтует с целевым ресурсом . Поскольку целевой ресурс еще не был опубликован, он не может конфликтовать, и поэтому отвечать на409 Conflict
него не имеет никакого смысла.POST
, на самом деле, я бы сделал вывод об обратном, потому что «конфликты чаще всего возникают в ответ на запрос PUT». кажется, указывает, что другие методы запроса также могут использовать этот код. Кроме того, «тело ответа должно включать в себя достаточно информации, чтобы пользователь мог распознать источник конфликта. В идеале, объект ответа должен включать в себя достаточно информации, чтобы пользователь или пользовательский агент мог решить проблему; однако это может быть невозможно и не требуется . " ( webdav.org/specs/rfc2616.html#status.409 )«302 найдено» звучит логично для меня. И RFC 2616 говорит, что на него МОЖНО ответить на другие запросы, кроме GET и HEAD (и это, безусловно, включает POST)
Но он по-прежнему удерживает посетителя, переходящего по этому URL, чтобы получить этот ресурс «Найдено» в RFC. Чтобы перейти непосредственно к реальному «найденному» URL-адресу, нужно использовать «303 См. Другое», что имеет смысл, но заставляет другой вызов получить свой следующий URL-адрес. С хорошей стороны, этот GET кешируется.
Я думаю, что я бы использовал "303 см. Другие" . Я не знаю, смогу ли я ответить "вещью", найденной в теле, но я хотел бы сделать это, чтобы сохранить одну поездку на сервер.
ОБНОВЛЕНИЕ: после перечитывания RFC я все еще думаю, что несуществующий код " 4XX + 303 Found" должен быть правильным. Однако «Конфликт 409» - это лучший из существующих кодов ответов (как указано @Wrikken), возможно, включающий заголовок Location, указывающий на существующий ресурс.
источник
Я не думаю, что вы должны это делать.
Как вы знаете, POST изменяет коллекцию и используется для СОЗДАНИЯ нового элемента. Итак, если вы отправляете идентификатор (я думаю, что это не очень хорошая идея), вам следует изменить коллекцию, т. Е. Изменить элемент, но это сбивает с толку.
Используйте его, чтобы добавить элемент без идентификатора. Это лучшая практика.
Если вы хотите захватить УНИКАЛЬНОЕ ограничение (не идентификатор), вы можете ответить 409, как вы можете сделать в запросах PUT. Но не удостоверение личности.
источник
Я хотел бы пойти с
422 Unprocessable Entity
, который используется, когда запрос является недействительным, но проблема не в синтаксисе или аутентификации.В качестве аргумента против других ответов использование любого
4xx
кода без ошибок подразумевает, что это не ошибка клиента, и это, очевидно, так. Использовать4xx
код без ошибок для представления ошибки клиента просто не имеет никакого смысла.Кажется, что
409 Conflict
это самый распространенный ответ здесь, но, согласно спецификации, это означает, что ресурс уже существует, и новые данные, которые вы применяете к нему, несовместимы с его текущим состоянием. Если вы отправляетеPOST
запросите, например, имя пользователя, которое уже занято, фактически не конфликтует с целевым ресурсом, поскольку целевой ресурс (ресурс, который вы пытаетесь создать) еще не был опубликован. Это ошибка специально для контроля версий, когда существует конфликт между версией хранимого ресурса и запрашиваемой версией ресурса. Это очень полезно для этой цели, например, когда клиент кэширует старую версию ресурса и отправляет запрос на основе этой неверной версии, которая больше не будет условно допустимой. «В этом случае представление ответа, вероятно, будет содержать информацию, полезную для объединения различий на основе истории изменений». Запрос на создание другого пользователя с таким именем просто не обрабатывается, не имеет никакого отношения к управлению версиями.Напомним, что 422 также является кодом состояния, который GitHub использует, когда вы пытаетесь создать хранилище по имени, которое уже используется.
источник
Я думаю, что для REST, вы просто должны принять решение о поведении для этой конкретной системы, и в этом случае, я думаю, что «правильный» ответ будет одним из пары ответов, приведенных здесь. Если вы хотите, чтобы запрос прекратился и вел себя так, как если бы клиент допустил ошибку, которую он должен исправить перед продолжением, используйте 409. Если конфликт действительно не так важен и вы хотите, чтобы запрос продолжался, ответьте, перенаправив запрос клиент сущности, которая была найдена. Я думаю, что правильные API REST должны перенаправлять (или, по крайней мере, предоставлять заголовок местоположения) конечную точку GET для этого ресурса после POST в любом случае, так что такое поведение даст согласованный опыт.
РЕДАКТИРОВАТЬ: Стоит также отметить, что вы должны рассмотреть PUT, так как вы предоставляете ID. Тогда поведение простое: «Мне все равно, что там сейчас, положите эту вещь туда». То есть, если там ничего нет, оно будет создано; если что-то есть, оно будет заменено. Я думаю, что POST является более подходящим, когда сервер управляет этим ID. Разделение двух понятий в основном говорит вам, как с этим бороться (то есть PUT является идемпотентом, поэтому он должен всегда работать до тех пор, пока полезная нагрузка проверяется, POST всегда создает, поэтому, если есть коллизия идентификаторов, то 409 описывает этот конфликт) ,
источник
POST
запросом (при правильном использовании), поскольку в нем говорится, что он должен быть возвращен, когда он конфликтует с целевым ресурсом . Поскольку целевой ресурс еще не был опубликован, он не может конфликтовать, и поэтому отвечать на409 Conflict
него не имеет никакого смысла.PUT
хотя.В конце концов, еще одно потенциальное лечение - использование PATCH. PATCH определяется как то, что изменяет внутреннее состояние и не ограничивается добавлением.
PATCH решит проблему, позволив вам обновить уже существующие элементы. См .: RFC 5789: PATCH
источник
Почему не принят 202 ? Это нормальный запрос (200 с), клиентских ошибок (400 с) как таковых не было.
Из 10 определений кода состояния :
... потому что его не нужно было завершать, потому что он уже существовал. Клиент не знает, что он уже существует, он не сделал ничего плохого.
Я полагаюсь на 202 и возвращаю содержимое, похожее на то,
/{resource}/{id}
что вернул бы GET .источник
Наткнулся на этот вопрос при проверке правильности кода для дубликата записи.
Прошу прощения за мое невежество, но я не понимаю, почему все игнорируют код «300», который четко говорит «множественный выбор» или «неоднозначный»
На мой взгляд, это был бы идеальный код для создания нестандартной или конкретной системы для вашего собственного использования. Я тоже могу ошибаться!
https://tools.ietf.org/html/rfc7231#section-6.4.1
источник
Скорее это
400 Bad Request
Поскольку запрос содержит повторяющееся значение (значение, которое уже существует), его можно воспринимать как ошибку клиента. Необходимо изменить запрос перед следующей попыткой.
Учитывая эти факты, мы можем сделать вывод, что HTTP STATUS 400 Bad Request.
источник
Как насчет 208 - http://httpstatusdogs.com/208-already-reported ? Это вариант?
На мой взгляд, если единственное, что является повторным ресурсом, то не должно быть ошибок. В конце концов, нет ошибок ни на стороне клиента, ни на стороне сервера.
источник
В вашем случае вы можете использовать
409 Conflict
И если вы хотите проверить другие
HTTPs
коды состояния из списка ниже1 × × Информационный
2 × × Успех
3 × × Перенаправление
4 × × Ошибка клиента
5 × × Ошибка сервера
источник