Решение о том, использовать ли PUT или POST для создания ресурса на сервере с HTTP + REST API, зависит от того, кто владеет структурой URL. Наличие у клиента информации или участие в определении, структура URL является ненужной связью, сродни нежелательным связям, возникшим в SOA. Экранирование типов муфт является причиной популярности REST. Следовательно, правильный метод для использования - это POST. Существуют исключения из этого правила, и они возникают, когда клиент желает сохранить контроль над структурой расположения ресурсов, которые он развертывает. Это редко и, вероятно, означает, что что-то не так.
На этом этапе некоторые люди утверждают, что если используются RESTful-URL , клиент знает URL-адрес ресурса и, следовательно, PUT является приемлемым. В конце концов, именно поэтому важны канонические, нормализованные URL-адреса Ruby on Rails, Django, посмотрите на API Twitter… бла-бла-бла. Эти люди должны понимать, , что нет такой вещи, как Restful-URL , и что Рой Филдинг сам утверждает, что :
REST API не должен определять фиксированные имена ресурсов или иерархии (
очевидная связь клиента и сервера). Серверы должны иметь свободу
контролировать свое собственное пространство имен. Вместо этого позвольте серверам инструктировать
клиенты о том, как создать соответствующие URI, например, в HTML
формы и шаблоны URI, определяя эти инструкции в медиа
типы и связи связей. [Ошибка здесь подразумевает, что клиенты
предполагая структуру ресурса из-за внеполосной информации, такой как
предметно-ориентированный стандарт, который является ориентированным на данные эквивалентом
Функциональная связь RPC].
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
Идея RESTful-URL на самом деле является нарушением REST, поскольку сервер отвечает за структуру URL-адреса и должен иметь возможность самостоятельно решать, как его использовать, чтобы избежать связывания. Если это вас смущает, читайте о значении самопознания для разработки API.
Использование POST для создания ресурсов требует разработки, поскольку POST не идемпотентен. Это означает, что повторение POST несколько раз не гарантирует одно и то же поведение каждый раз. Это пугает людей использованием PUT для создания ресурсов, когда они не должны. Они знают, что это неправильно (POST для CREATE), но они все равно делают это, потому что не знают, как решить эту проблему. Эта проблема проявляется в следующей ситуации:
- Клиент отправляет новый ресурс на сервер.
- Сервер обрабатывает запрос и отправляет ответ.
- Клиент никогда не получает ответ.
- Сервер не знает, что клиент не получил ответ.
- У клиента нет URL для ресурса (поэтому PUT не является опцией) и повторяется POST.
- POST не идемпотент и сервер…
На шестом этапе люди обычно не понимают, что делать. Тем не менее, нет никаких причин для создания этой проблемы. Вместо этого можно использовать HTTP, как указано в RFC 2616 , и сервер отвечает:
10.4.10 409 Конфликт
Запрос не может быть выполнен из-за конфликта с текущим
состояние ресурса. Этот код разрешен только в ситуациях, когда
ожидается, что пользователь сможет разрешить конфликт и
повторно отправить запрос. Тело ответа ДОЛЖНО включать
информация для пользователя, чтобы распознать источник конфликта.
В идеале объект ответа должен включать в себя достаточно информации для
пользователь или пользовательский агент для решения проблемы; однако, это не может быть
возможно и не требуется.
Конфликты чаще всего возникают в ответ на запрос PUT. За
Например, если использовались версии, а объект был PUT
включены изменения в ресурс, которые противоречат тем, которые были сделаны
еазапрос rlier (сторонний), сервер может использовать ответ 409
чтобы указать, что он не может выполнить запрос. В этом случае
Ответный объект, скорее всего, будет содержать список различий между
две версии в формате, определенном в ответе Content-Type.
Ответ с кодом состояния 409 Конфликт является правильным решением, потому что :
- Выполнение POST-данных с идентификатором, совпадающим с ресурсом, уже находящимся в системе, является «конфликтом с текущим состоянием ресурса».
- Поскольку важная часть заключается в том, чтобы клиент понимал, что сервер имеет ресурс, и предпринимал соответствующие действия. Это «ситуация (ситуации), когда ожидается, что пользователь сможет разрешить конфликт и повторно отправить запрос».
- Ответ, содержащий URL-адрес ресурса с конфликтующим идентификатором и соответствующие предварительные условия для ресурса, предоставит «достаточно информации для пользователя или пользовательского агента для решения проблемы», что является идеальным случаем в соответствии с RFC 2616.
Обновление на основе выпуска RFC 7231 для замены 2616
RFC 7231 предназначен для замены 2616 и в Раздел 4.3.3 описывает следующие возможные ответы для POST
Если результат обработки POST будет эквивалентен
представление существующего ресурса, сервер источника МОЖЕТ перенаправить
пользовательский агент на этот ресурс, отправив ответ 303 (см. Другие)
с идентификатором существующего ресурса в поле Location. это
имеет преимущества предоставления агенту пользователя идентификатора ресурса
и передача представления с помощью метода, более поддающегося
совместное кэширование, хотя за счет дополнительного запроса, если пользователь
Агент еще не имеет кэшированного представления.
Теперь может возникнуть соблазн просто вернуть 303 в случае повторения POST. Однако обратное верно. Возврат 303 имеет смысл, только если несколько запросов на создание (создание разных ресурсов) возвращают один и тот же контент. В качестве примера можно привести «спасибо за отправку сообщения с запросом», которое клиент не должен повторно загружать каждый раз. RFC 7231 по-прежнему утверждает в разделе 4.2.2, что POST не должен быть идемпотентным, и продолжает утверждать, что POST должен использоваться для создания.
Подробнее об этом читайте в статье .