Код ответа HTTP для сообщения, когда ресурс уже существует



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



Я определил API, чтобы клиенты могли создавать или изменять объекты с помощью PUT:



PUT /objects/{id} HTTP/1.1
...

{json representation of the object}


{id} - это идентификатор объекта, поэтому он является частью запроса-URI.



теперь я также рассматриваю возможность разрешить клиентам создавать объект с помощью Сообщение:



POST /objects/ HTTP/1.1
...

{json representation of the object, including ID}


поскольку POST означает операцию "добавить", я не уверен, что делать, если объект уже существует. Должен ли я рассматривать запрос как запрос на изменение или я должен вернуть некоторый код ошибки (который)?

637   15  

15 ответов:

Мне кажется 409 Conflict является наиболее подходящим, однако, редко встречается в дикой природе:

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

конфликты, скорее всего, возникнут в ответ на запрос PUT. Например, если используется управление версиями и помещаемый объект включает изменения в ресурс, которые конфликтуют с теми, которые были сделаны более ранним (сторонним) запросом, сервер может использовать ответ 409, чтобы указать, что он не может выполнить запрос. В этом случае объект ответа, скорее всего, будет содержать список различий между двумя версиями в формате, определенном типом содержимого ответа.

лично я иду с расширением WebDAV 422 Unprocessable Entity.

REST Patterns описывает его как

The 422 Unprocessable Entity код состояния означает, что сервер понимает тип содержимого объекта запроса (следовательно, a 415 Unsupported Media Type код состояния неуместен), и синтаксис объекта запроса является правильным (таким образом, a 400 Bad Request код состояния неуместен), но не смог обработать содержащиеся инструкции.

по данным RFC 7231, a 303 См. Другие можно использовать если результат обработки сообщения будет эквивалентен a представление существующего ресурса.

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

чтобы немного расширить ответ Wrikken, я думаю, вы могли бы использовать либо 409 Conflict или 403 Forbidden в зависимости от ситуации - короче говоря, используйте ошибку 403, когда пользователь не может ничего сделать для разрешения конфликта и завершения запроса (например, они не могут отправить DELETE запрос на явное удаление ресурса), или использовать 409, если что-то может быть сделанный.

10.4.4 403 запрещено

сервер понял запрос, но отказывается выполнять его. Авторизация не поможет, и запрос не должен повторяться. Если метод запроса не был HEAD и сервер хочет сделать общедоступным почему запрос не был выполнен, он должен описать причину за отказ в юридическом лице. Если сервер не желает делать эта информация доступна клиенту, код состояния 404 (не Найдено) можно использовать вместо этого.

в настоящее время кто-то говорит "403", и на ум приходит проблема с разрешениями или аутентификацией, но спецификация говорит, что в основном сервер говорит клиенту, что он не собирается этого делать, не спрашивайте его снова, и вот почему клиент не должен.

по состоянию на PUT и POST... POST должен использоваться для создания нового экземпляра ресурса, когда пользователь не имеет средств или не должен создавать идентификатор для ресурс. PUT используется, когда идентификатор ресурса известен.

9.6 PUT

...

принципиальная разница между запросами POST и PUT находит свое отражение в различном значении URI в запросе. URI в a Запрос POST идентифицирует ресурс, который будет обрабатывать прилагается сущность. Этот ресурс может быть процессом приема данных, шлюзом для какой-то другой протокол или отдельный объект, который принимает аннотации. В напротив, URI в запросе put идентифицирует объект, заключенный с запрос -- агент пользователя знает, что URI предназначен и сервер не должен пытаться применить запрос к какому-либо другому ресурсу. Если сервер желает, чтобы запрос был применен к другому URI,

он должен отправить 301 (постоянно перемещенный) ответ; агент пользователя может затем принять свое собственное решение относительно того, следует ли перенаправить запрос.

Как насчет возвращения 418?

поскольку клиент просит сохранить сущность, которая уже существует на сервере, сервер, наконец, злится и думает, что он чайник и возвращает:418 I'm a teapot.

ссылки:

"302 найдено" звучит логично для меня. А то RFC 2616 говорит, что на него можно ответить на другие запросы, чем GET и HEAD (и это, безусловно, включает в себя POST)

но он все еще держит посетителя, идущего на этот URL, чтобы получить этот "найденный" ресурс, RFC. Чтобы заставить его перейти непосредственно к реальному "найденному" URL, нужно использовать "303 See Other", что имеет смысл, но заставляет другой вызов получить его следующий URL. С хорошей стороны, это получить это кэшируемый.

думаю, что Я бы использовал "303 см. Другие". Я не знаю, Могу ли я ответить с помощью "вещи", найденной в теле, но я хотел бы сделать это, чтобы сохранить одну поездку туда и обратно на сервер.

обновление: после перечитывания RFC, я все еще думаю, что отсутствует "4xx+303 найдено" код должен быть правильным. Тем не менее, "409 конфликт" является лучшим существующим кодом ответа (как указано @ Wrikken), возможно, включая a Заголовок местоположения, указывающий на существующий ресурс.

Я не думаю, что вы должны сделать это.

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

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

Если вы хотите захватить уникальное ограничение(не идентификатор), вы можете ответить 409, как вы можете сделать в запросах PUT. Но не ИДЕНТИФИКАТОР.

почему бы и нет 202 принято? Это ОК запрос (200s), не было никаких ошибок клиента (400s), по сути.

С 10 Определений Кода Состояния:

"202 принято. Запрос был принят для обработки, но обработка не была завершена."

... потому что ее не нужно было завершать, потому что она уже существовала. Клиент не знает, что он уже существовал, они ничего не сделали неправильный.

Я опираюсь на бросок 202, и возвращаю аналогичный контент, чтобы получить /{resource}/{id} вернули бы.

Я думаю, что для отдыха вам просто нужно принять решение о поведении для этой конкретной системы, и в этом случае я думаю, что "правильный" ответ будет одним из нескольких ответов, приведенных здесь. Если вы хотите, чтобы запрос остановился и вел себя так, как если бы клиент допустил ошибку, которую он должен исправить перед продолжением, то используйте 409. Если конфликт действительно не так важен и вы хотите сохранить запрос, то ответьте, перенаправив клиента на объект, который был найден. Я думаю, что правильный отдых API должно быть перенаправление (или, по крайней мере, предоставление заголовка location) в конечную точку GET для этого ресурса после публикации в любом случае, поэтому это поведение даст согласованный опыт.

изменить: Также стоит отметить, что вы должны рассмотреть PUT, так как вы предоставляете идентификатор. Тогда поведение просто: "мне все равно, что там сейчас, положите эту вещь туда.- То есть, если там ничего нет, оно будет создано; если там что-то есть, оно будет заменено. Я думаю, что пост больше если сервер управляет этим идентификатором. Разделение двух концепций в основном говорит вам, как с этим бороться (т. е. PUT является идемпотентным, поэтому он всегда должен работать до тех пор, пока полезная нагрузка проверяется, POST всегда создает, поэтому, если есть столкновение идентификаторов, то 409 будет описывать этот конфликт).

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

патч решит проблему, позволяя вам обновлять уже существующие элементы. Смотрите:RFC 5789: ПАТЧ

Я бы пошел с 422 Unprocessable Entity, который используется, когда запрос является недопустимым, но проблема не в синтаксисе или аутентификации.

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

кажется,409 Conflict является наиболее распространенным ответом здесь, но, согласно спецификации, это означает, что ресурс уже существует, и новые данные, которые вы применяете к нему, несовместимы с его текущим состоянием. Если вы отправляете POST запрос, например, с уже принятым именем пользователя, на самом деле не конфликтует с целевым ресурсом, поскольку целевой ресурс еще не был отправлен. Это ошибка специально для контроля версий, когда существует конфликт между версией сохраненного ресурса и версией запрошенного ресурса. Это очень полезно для этой цели, ибо пример, когда клиент кэширует старую версию ресурса и отправляет запрос на основе этой неправильной версии, которая больше не будет условно допустимой. "В этом случае представление ответа, вероятно, будет содержать информацию, полезную для объединения различий на основе истории пересмотра."Запрос на создание другого пользователя с этим именем пользователя просто необработан, не имея ничего общего с контролем версий.

для записи, 422 также код состояния GitHub при попытке создать хранилище по имя уже используется.

насчет 208 - http://httpstatusdogs.com/208-already-reported ? Это вариант?

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

наткнулся на этот вопрос при проверке правильного кода для дубликата записи.

простите мое невежество, но я не понимаю, почему все игнорируют код "300", который четко говорит "множественный выбор" или "неоднозначный"

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

https://tools.ietf.org/html/rfc7231#section-6.4.1

скорее это 400 Bad Request

6.5.1. 400 Плохой Запрос


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

так как запрос содержит повторяющееся значение(value это уже существует), это может быть воспринято как ошибка клиента. Нужно изменить запрос перед следующей попыткой.
Рассматривая эти факты, мы можем заключить, что HTTP STATUS 400 Bad Request.

Это все контекст, а также кто несет ответственность за наличие дубликатов (сервер или клиент или оба)

Если сервер просто точка дубликат, посмотрите на 4xx:

  • 400 плохой запрос - когда сервер не будет обрабатывать запрос, потому что это очевидная ошибка клиента
  • 409 конфликт - если сервер не будет обрабатывать запрос, но причина этого не является ошибкой клиента

для подразумевается обработка дубликатов, посмотрите на 2XX:

  • 200 ОК
  • 201 создан

если сервер ожидал что-то вернуть, посмотрите на 3XX:

  • 302 нашел
  • 303 См. Другие

когда сервер может указывать на существующий ресурс, подразумевает перенаправление.

Если выше не достаточно, это всегда хорошая практика, приготовить сообщение об ошибке в теле ответа.

Comments

    Ничего не найдено.