Поставить и пост в покое

согласно спецификации HTTP / 1.1:

на POST метод используется для запроса, чтобы исходный сервер принял сущность, заключенную в запросе, в качестве нового подчиненного ресурса, идентифицированного Request-URI на Request-Line

другими словами, POST используется создать.

на PUT метод запрашивает, чтобы вложенный объект хранился под предоставленным Request-URI. Если Request-URI относится к уже существующему ресурсу, вложенный объект следует рассматривать как измененную версию того, который находится на исходном сервере. Если Request-URI не указывает на существующий ресурс, и что URI может быть определен как новый ресурс запрашивающим агентом пользователя, исходный сервер может создать ресурс с этим URI."

то есть PUT используется создать или обновить.

Итак, какой из них следует ли использовать для создания ресурса? Или нужно поддерживать и то, и другое?

30 ответов


в целом:

для создания можно использовать как PUT, так и POST.

вы должны спросить: "для чего вы выполняете действие?- чтобы понять, что вы должны использовать. Предположим, вы разрабатываете API для вопросов. Если вы хотите использовать POST, вы сделаете это со списком вопросов. Если вы хотите использовать PUT, вы бы сделали это с конкретным вопросом.

большие оба можно использовать, так что какой из них я должен использовать в мой спокойный дизайн:

вам не нужно поддерживать как PUT, так и POST.

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

некоторые соображения:

  • вы называете свои объекты URL, которые вы создаете явно, или позволяете серверу решать? Если вы назовете их, используйте PUT. Если вы позволите серверу решить, используйте POST.
  • ставим это идемпотентно, поэтому, если вы поместите объект дважды, он не имеет никакого эффекта. Это хорошее свойство, поэтому я бы использовал PUT, когда это возможно.
  • вы можете обновить или создать ресурс с помощью PUT с тем же URL объекта
  • С POST вы можете иметь 2 запроса, поступающих в то же время внесения изменений в URL, и они могут обновлять различные части объекта.

пример:

я написал следующее как часть другого ответьте на так относительно этого:

сообщение:

изменить и обновить ресурс

POST /questions/<existing_question> HTTP/1.1
Host: www.example.com/

обратите внимание, что следующая ошибка:

POST /questions/<new_question> HTTP/1.1
Host: www.example.com/

если URL еще не создан, вы не надо через пост создать при указании имени. Это должно результат в "ресурс не найден" ошибка потому что <new_question> не существует еще. Вы должны поставить <new_question> ресурс по первый сервер.

вы могли бы сделать что-то вроде для создания ресурсов с помощью POST:

POST /questions HTTP/1.1
Host: www.example.com/

отметим, что в этом случае ресурс имя не указано, новые объекты URL-адрес будет возвращен вам.

поставить:

используется для создания ресурса, или перезаписать его. Пока вы указываете ресурсы новый URL-адрес.

для нового ресурса:

PUT /questions/<new_question> HTTP/1.1
Host: www.example.com/

в перезаписать существующий ресурс:

PUT /questions/<existing_question> HTTP/1.1
Host: www.example.com/

вы можете найти утверждения в интернете, что сказать

не совсем верно.


лучше выбирать между PUT и POST на основе idempotence действия.

поставить подразумевает размещение ресурса-полностью заменяя все, что доступно по данному URL-адресу, другой вещью. По определению, PUT является идемпотентным. Делайте это столько раз, сколько хотите, и результат будет тот же. x=5 идемпотентна. Вы можете поместить ресурс, существует ли он ранее или нет (например, для создания или обновления)!

в должности обновляет ресурс, добавляет дочернюю компанию ресурс, или вызывает изменение. Пост не является идемпотентным, в том смысле, что x++ не является идемпотентной.


по этому аргументу PUT предназначен для создания, когда вы знаете URL-адрес вещи, которую вы создадите. POST можно использовать для создания, когда вы знаете URL-адрес "фабрики" или менеджера для категории вещей, которые вы хотите создать.

так:

POST /expense-report

или:

PUT  /expense-report/10929

  • в должности к URL создает дочерний ресурс на сервера URL-адрес.
  • поставить к URL создает / заменяет ресурс в полном объеме в клиент определенными URL-адрес.
  • патч к URL обновления часть ресурс в этом клиенте определен URL.

уместная спецификация для положенного и Сообщение RFC 2616 §9.5 ff.

POST создает дочерний ресурс, так что сообщение /items создает ресурсы, которые живут под /items ресурсов. Например. /items/1. Отправка одного и того же почтового пакета дважды создаст два ресурса.

поставить предназначен для создания или замены ресурса в URL, известный клиенту.

таким образом: поставить является только кандидатом на создание, где клиент уже знает url-адрес до создания ресурса. Например. /blogs/nigel/entry/when_to_use_post_vs_put в качестве заголовка используется ключ ресурса

поставить заменяет ресурс по известному url-адресу, если он уже существует, поэтому отправка одного и того же запроса дважды не имеет эффекта. Другими словами,вызовы поставить являются идемпотентными.

RFC читает так:

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

Примечание: PUT в основном использовался для обновления ресурсов (путем их замены в их полноте), но в последнее время наблюдается движение к использованию патча для обновления существующих ресурсов, поскольку PUT указывает, что он заменяет весь ресурс. RFC 5789.


резюме:

создать:

может выполняться как с PUT или POST следующим образом:

поставить

создает на новый ресурс с newResourceId в качестве идентификатора под URI / resources или коллекция.

PUT /resources/<newResourceId> HTTP/1.1 

в должности

создает A новый ресурс в URI / resources, или коллекция. Обычно идентификатор возвращается сервером.

POST /resources HTTP/1.1

обновление:

Can только выполняется с помощью PUT следующим образом:

поставить

обновляет ресурс с помощью existingResourceId в качестве идентификатора под URI / resources или коллекция.

PUT /resources/<existingResourceId> HTTP/1.1

объяснение:

при общении с REST и URI как генерал, у вас есть generic на левый и конкретные на право. The дженериков обычно называют коллекции и больше конкретные элементы можно назвать ресурс. Обратите внимание, что ресурс может содержать коллекция.

примеры:

URI: website.com/users/john
website.com  - whole site
users        - collection of users
john         - item of the collection, or a resource

URI:website.com/users/john/posts/23
website.com  - whole site
users        - collection of users
john         - item of the collection, or a resource
posts        - collection of posts from john
23           - post from john with identifier 23, also a resource

при использовании POST вы всегда обращаясь к коллекция, поэтому всякий раз, когда вы говорите:

POST /users HTTP/1.1

вы отправляете нового пользователя в пользователи коллекция.

если вы продолжите и попробуете что-то вроде этого:

POST /users/john HTTP/1.1

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

как только вы используете PUT, вы ссылаетесь на ресурс или один элемент, возможно, внутри коллекция. Поэтому, когда вы говорите:

PUT /users/john HTTP/1.1

вы сообщаете обновление сервера или создаете, если оно не существует,Джон ресурс под пользователи коллекция.

Spec:

позвольте мне выделить некоторые важные части спецификации:

в должности

на в должности метод используется для запроса, что сервер-источник принимать сущность, заключенная в запросе как новая в подчинении ресурса, идентифицированного запросом-URI в строке запроса

следовательно, создает ресурс на коллекция.

поставить

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

следовательно, создайте или обновите на основе существования ресурс.

ссылки:


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

Итак: для сохранения существующего пользователя или того, где клиент генерирует идентификатор, и было проверено, что идентификатор уникален:

PUT /user/12345 HTTP/1.1  <-- create the user providing the id 12345
Host: mydomain.com

GET /user/12345 HTTP/1.1  <-- return that user
Host: mydomain.com

в противном случае используйте POST для первоначального создания объекта и PUT для обновления объект:

POST /user HTTP/1.1   <--- create the user, server returns 12345
Host: mydomain.com

PUT /user/12345 HTTP/1.1  <--- update the user
Host: mydomain.com

POST означает "создать новый", как в"вот вход для создания пользователя, создайте его для меня".

PUT означает "вставить, заменить, если уже существует", как в"вот данные для пользователя 5".

вы отправляете сообщение example.com/users поскольку вы еще не знаете URL-адрес пользователя, вы хотите, чтобы сервер его создал.

вы ставите example.com/users/id поскольку вы хотите заменить / создать конкретные пользователей.

проводка дважды с теми же данными означает создайте двух одинаковых пользователей с разными идентификаторами. Размещение дважды с одними и теми же данными создает пользователя первым и обновляет его до того же состояния во второй раз (без изменений). Поскольку вы оказываетесь в одном и том же состоянии после пут, независимо от того, сколько раз вы его выполняете, говорят, что он "одинаково мощный" каждый раз - идемпотентный. Это полезно для автоматического повторного выполнения запросов. Нет больше 'вы уверены, что хотите отправить' когда вы нажимаете кнопку Назад в браузере.

общий совет используйте POST, когда вам нужно, чтобы сервер контролировал создание URL-адресов ваших ресурсов. Использовать иначе. Предпочитаю поставить над постом.


используйте POST для создания и PUT для обновления. Во всяком случае, так делает Ruby on Rails.

PUT    /items/1      #=> update
POST   /items        #=> create

отдых-это очень высокого уровня. На самом деле, он даже не упоминает HTTP вообще!

Если у вас есть какие-либо сомнения относительно того, как реализовать REST в HTTP, вы всегда можете взглянуть на Протокол Публикации Atom (AtomPub) спецификация. AtomPub-это стандарт для написания веб-сервисов RESTful с HTTP, который был разработан многими HTTP и REST светилами, с некоторыми входными данными от Роя Филдинга, изобретателя REST и (со)изобретателя HTTP себя.

на самом деле, вы даже можете использовать AtomPub напрямую. Хотя он вышел из сообщества блогов, он никоим образом не ограничен блогами: это общий протокол для спокойного взаимодействия с произвольными (вложенными) коллекциями произвольных ресурсов через HTTP. Если вы можете представить свое приложение как вложенную коллекцию ресурсов, вы можете просто использовать AtomPub и не беспокоиться о том, использовать ли PUT или POST, Какие коды состояния HTTP для возврата и все это подробности.

вот что AtomPub должен сказать о создании ресурсов (раздел 9.2):

чтобы добавить членов в коллекцию, клиенты отправляют запросы POST в URI коллекции.


решение о том, использовать ли PUT или POST для создания ресурса на сервере с API HTTP + REST, основано на том, кому принадлежит структура URL. Если клиент знает или участвует в определении, структура URL-адреса является ненужной связью, сродни нежелательным связям, которые возникли из SOA. Избегая типы соединений причина отдых настолько популярен. Следовательно,правильный метод для использования-POST. есть исключения из этого правила, и они возникают, когда клиент хочет сохранить контроль над структурой расположения развертываемых ресурсов. Это редкость и, вероятно, означает, что что-то еще не так.

в этот момент некоторые люди утверждают, что если спокойного URL-адрес используются, клиент знает URL-адрес ресурса, и поэтому PUT является приемлемым. В конце концов, именно поэтому важны канонические, нормализованные, Ruby on Rails, URL-адреса Django, посмотрите на API Twitter ... бла-бла-бла. Эти люди должны понять нет такой вещи, как Restful-URL и Сам Рой Филдинг утверждает, что:

API REST не должен определять фиксированные имена ресурсов или иерархии (an очевидная связь клиента и сервера). Серверы должны иметь свободу управлять собственным пространством имен. Вместо этого разрешите серверам инструктировать клиенты о том, как создать соответствующие URI, например, в HTML формы и шаблоны URI, определяя эти инструкции на носителе типы и связи. [Неудача здесь подразумевает, что клиенты предполагая структуру ресурсов из-за внеполосной информации, такой как домен-специфический стандарт, который является ориентированным на данные эквивалентом Функциональная муфта RPC].

http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

идея RESTful-URL на самом деле является нарушением REST, поскольку сервер отвечает за структуру URL и должен быть свободен, чтобы решить, как использовать его, чтобы избежать сцепки. Если это смущает, Вы читаете о значении самостоятельного обнаружения в дизайне API.

использование POST для создания ресурсов поставляется с учетом дизайна, потому что POST не является идемпотентным. это означает, что повторение сообщения несколько раз не гарантирует одно и то же поведение каждый раз. это пугает людей в использовании PUT для создания ресурсов, когда они не должны. Они знают, что это неправильно (сообщение для CREATE), но они все равно это делают, потому что не знают, как решить эту проблему. Эта озабоченность проявляется в следующей ситуации:

  1. клиент отправляет новый ресурс на сервер.
  2. сервер обрабатывает запрос и отправляет ответ.
  3. клиент никогда не получает ответ.
  4. сервер не знает, что клиент не получил ответ.
  5. у клиента нет URL-адреса для ресурса (поэтому PUT не является вариантом) и повторяет сообщение.
  6. POST не идемпотентный и сервер ...

Шаг 6-это то, где люди обычно путаются в том, что делать. Однако нет причин создавать kludge для решения этой проблемы. Вместо этого HTTP можно использовать, как указано в RFC 2616 а сервер отвечает:

10.4.10 409 конфликт

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

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

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

ответ с кодом состояния 409 конфликта является правильным обращением, потому что:

  • выполнение записи данных с идентификатором, который соответствует ресурсу, уже находящемуся в системе, является " конфликтом с текущим состоянием ресурса."
  • так как важная часть для клиента, чтобы понять, что сервер имеет ресурс и принять соответствующие меры. Это " ситуация(ситуации), когда ожидается, что пользователь может разрешить конфликт и повторно отправить запрос."
  • ответ, который содержит URL ресурса с конфликтующим идентификатором и соответствующими предварительными условиями для ресурса, предоставит "достаточную информацию для пользователя или агента пользователя, чтобы устранить проблему", что является идеальным случаем для RFC 2616.

обновление на основе выпуска RFC 7231 для замены 2616

RFC 7231 предназначен для замены 2616 и в 4.3.3 описывает следующий возможный ответ для сообщения

Если результат обработки поста будет эквивалентен представление существующего ресурса, исходный сервер может перенаправить агент пользователя на этот ресурс, отправив ответ 303 (см. Другие) с идентификатором существующего ресурса в поле расположение. Этот имеет преимущества предоставления агенту пользователя идентификатора ресурса и передачи представление с помощью метода, более поддающегося общее кэширование, хотя и за счет дополнительного запроса, если пользователь у агента еще нет кэшированного представления.

теперь может возникнуть соблазн просто вернуть 303 в случае, если сообщение повторяется. Однако верно обратное. Возврат 303 имеет смысл только в том случае, если несколько запросов на создание (создание разных ресурсов) возвращают один и тот же контент. Примером может быть "Спасибо за отправку запроса сообщение " что клиенту не нужно повторно загружать каждый раз. RFC 7231 по-прежнему утверждает в разделе 4.2.2, что POST не должен быть идемпотентным и продолжает поддерживать, что POST должен использоваться для создания.

для получения дополнительной информации об этом, почитайте вот это статьи.


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

Enter image description here

аналогия:

  • поставить т. е. взять и поставить где это было.
  • сообщение как отправить почту в в должности офис.

enter image description here


Мне нравится этот совет, от определение PUT RFC 2616:

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

Это совпадает с другим советом здесь, что PUT лучше всего применяется к ресурсам, которые уже имеют имя, и POST хорош для создания нового объекта под существующим ресурсом (и позволяя серверу назвать его).

я интерпретирую это и требования идемпотентности на PUT, чтобы означать что:

  • POST хорош для создания новых объектов в коллекции (и create не обязательно должен быть идемпотентным)
  • PUT хорош для обновления существующих объектов (и обновление должно быть идемпотентным)
  • POST также может использоваться для неидемпотентных обновлений существующих объектов (особенно, изменение части объекта без указания всего - если вы думаете об этом, создание нового члена коллекции на самом деле является частным случаем такого рода обновления, с точки зрения коллекции)
  • PUT также может использоваться для создания, если и только если вы разрешите клиенту назвать ресурс. Но поскольку клиенты REST не должны делать предположений о структуре URL, это меньше в предполагаемом духе вещей.

короче:

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

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

аналогия с запросом базы данных

поставить вы можете думать о похожем на " обновление набора студентов address = "abc", где id= "123";

в должности вы можете придумать что-то вроде "вставить в значения STUDENT(name, address) ("abc", "xyzzz");

идентификатор студента генерируется автоматически.

с помощью PUT, если один и тот же запрос выполняется несколько раз или один раз, состояние таблицы STUDENT остается неизменным.

в случае POST, если один и тот же запрос выполняется несколько раз, то в базе данных и состоянии базы данных создается несколько студенческих записей изменения при каждом выполнении запроса" INSERT".

Примечание: PUT нуждается в местоположении ресурса (уже-resource), на котором должно произойти обновление, тогда как POST этого не требует. Поэтому интуитивно POST предназначен для создания нового ресурса, тогда как PUT необходим для обновления уже существующего ресурса.

некоторые могут придумать, что обновления могут быть выполнены с помощью POST. Нет жесткого правила, которое можно использовать для обновлений или использовать для создания. Опять же, это условности, и интуитивно я склоняюсь к вышеупомянутым рассуждениям и следую им.


POST - это как отправить письмо в почтовый ящик или отправить электронное письмо в очередь электронной почты. PUT-это когда вы кладете объект в ячейку или место на полке (у него есть известный адрес).

с помощью POST вы отправляете сообщение по адресу очереди или коллекции. С PUT, вы ставите по адресу элемента.

PUT является идемпотентным. Вы можете отправить запрос в 100 раз и это не будет иметь значения. Пост не является идемпотентной. Если вы отправите запрос 100 раз, вы получите 100 электронные письма или 100 писем в почтовом ящике.

общее правило: если вы знаете id или имя элемента, используйте PUT. Если вы хотите, чтобы идентификатор или имя элемента были назначены принимающей стороной, используйте POST.

POST versus PUT


новый ответ (теперь, когда я лучше понимаю остальных):

PUT-это просто заявление о том, какой контент сервис должен отныне использовать для визуализации представлений ресурса, идентифицированного клиентом; POST-это заявление о том, какой контент сервис должен отныне содержать (возможно, дублированный), но это зависит от сервера, как идентифицировать этот контент.

PUT x (Если x определяет ресурс): "заменить содержание ресурса, идентифицированного x С моим содержимым."

PUT x (Если x не идентифицирует ресурс): "создайте новый ресурс, содержащий мой контент и используйте x для установления его личности."

POST x: "сохраните мой контент и дайте мне идентификатор, который я могу использовать для идентификации ресурса (старого или нового), содержащего указанный контент (возможно, смешанный с другим контентом). Указанный ресурс должен быть идентичен или подчинен тому, который x идентифицирует." "yресурс подчиняется xресурс " обычно, но не обязательно реализуется путем создания y подпуть из x (например,x = /foo и y = /foo/bar) и изменение представления(ов)xресурс, чтобы отразить существование нового ресурса, например, с гиперссылкой на yресурс и некоторые метаданные. Только последнее действительно необходимо для добра. дизайн, поскольку URL-адреса непрозрачны в REST - вы должны использовать гипермедиа вместо построения URL на стороне клиента для обхода службы в любом случае.

в REST нет такой вещи, как ресурс, содержащий "контент". Я называю "содержимым" данные, которые служба использует для последовательного отображения представлений. Он обычно состоит из некоторых связанных строк в базе данных или файле (например, файл изображения). Это зависит от службы, чтобы преобразовать контент пользователя во что-то служба может использовать, например, преобразование полезной нагрузки JSON в операторы SQL.

оригинальный ответ (может быть легче читать):

PUT /something (если /something уже существует): "бери все, что у вас есть в /something и замените его тем, что я вам дам."

PUT /something (если /something еще не существует): "возьмите то, что я вам даю, и положите на /something."

POST /something: "возьмите то, что я вам даю, и положите его куда угодно под /something пока вы даете мне его URL, когда закончите."


Ruby on Rails 4.0 будет использовать метод "PATCH"вместо частичного обновления.

RFC 5789 говорит о патче (с 1995 года):

новый метод необходим для улучшения совместимости и предотвращения ошибки. Метод PUT уже определен для перезаписи ресурса с полным новым телом и не может быть повторно использован для частичных изменений. В противном случае прокси и кэши, а также клиенты и серверы могут получить смущен результатом операции. POST уже используется, но без широкой совместимости (для одного, нет стандартного способа открыть поддержка формата патч). Патч был упомянут в более раннем HTTP спецификации, но не полностью определены.

"Edge Rails: PATCH-это новый основной метод HTTP для обновлений", объясняет он.


Короткий Ответ:

простое эмпирическое правило: используйте POST для создания, используйте PUT для обновления.

Ответ:

сообщение:

  • POST используется для отправки данных на сервер.
  • полезно, когда URL-адрес ресурса неизвестно!--14-->

поставить:

  • PUT используется для передачи состояния на сервер
  • полезно, когда URL ресурса известно

Более Длинный Ответ:

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

с точки зрения архитектуры REST нет ничего, что имеет значение. Мы могли бы жить и без пут. Но с точки зрения клиента-разработчика это сделало его жизнь намного проще.

до PUT клиенты не могли напрямую знать URL-адрес, который сервер сгенерирован или если все они сгенерированы или данные, которые будут отправлены на сервер, уже обновлены или нет. Пут избавил разработчика от всех этих головных болей. PUT является идемпотентным, PUT обрабатывает условия гонки, и PUT позволяет клиенту выбрать URL.


рискуя повторить то, что уже было сказано, кажется важным помнить, что PUT подразумевает, что клиент контролирует, что URL-адресом собирается в конечном итоге, при создании ресурса. Так что часть выбора между PUT и в должности будет о том, насколько вы можете доверять клиенту, чтобы обеспечить правильный, нормализованный URL-адресом которые согласуются с любой вашей схемой URL.

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


наиболее важным фактором является надежность. Если сообщение POST теряется, состояние системы не определено. Автоматическое восстановление невозможно. Для сообщений PUT состояние не определено только до первой успешной повторной попытки.

например, это может быть не очень хорошая идея, чтобы создать транзакции кредитной карты с POST.

Если у вас есть автоматически сгенерированные URI на вашем ресурсе, вы все равно можете использовать PUT, передавая сгенерированный URI (указывая на пустой ресурс) клиенту.

некоторые другие соображения:

  • POST аннулирует кэшированные копии всего содержащего ресурса (лучшая согласованность)
  • PUT ответы не кэшируются в то время как POST те (требуется содержание-расположение и срок действия)
  • PUT меньше поддерживается, например, Java ME, старыми браузерами, брандмауэрами

очень простым способом я беру пример временной шкалы Facebook.

Случай 1: Когда вы публикуете что-то на своей временной шкале, это новая запись. Поэтому в этом случае они используют метод POST, потому что метод POST не является идемпотентным.

случай 2: Если ваш друг прокомментирует ваш пост в первый раз, это также создаст новую запись в базе данных, чтобы использовать метод POST.

Случай 3: Если ваш друг редактирует свой комментарий, в таком случае, у них был комментарий ID, поэтому они будут обновлять существующий комментарий вместо создания новой записи в базе данных. Поэтому для этого типа операции используйте метод PUT, поскольку он является идемпотентным.*

в одной строке, используйте в должности добавить новая запись в базе данных и поставить to обновление что-то в базе данных.


кажется, всегда есть некоторая путаница относительно того, когда использовать HTTP POST против метода HTTP PUT для служб REST. Большинство разработчиков попытаются связать операции CRUD непосредственно с методами HTTP. Я буду утверждать, что это неправильно, и нельзя просто связать понятия CRUD с методами HTTP. То есть:

Create => HTTP PUT
Retrieve => HTTP GET
Update => HTTP POST
Delete => HTTP DELETE

верно, что R(etrieve) и D (elete) операций CRUD могут быть сопоставлены непосредственно с методами HTTP GET и DELETE соответственно. Однако путаница заключается в операциях C(reate) и U(update). В некоторых случаях можно использовать PUT для создания, а в других случаях потребуется сообщение. Неоднозначность заключается в определении метода HTTP PUT по сравнению с методом HTTP POST.

согласно спецификациям HTTP 1.1 методы GET, HEAD, DELETE и PUT должны быть идемпотентными, а метод POST не является идемпотентным. То есть операция является идемпотентной, если она может быть выполнена на ресурсе один раз или много раз и всегда возвращайте одно и то же состояние этого ресурса. В то время как не идемпотентная операция может возвращать измененное состояние ресурса из одного запроса в другой. Следовательно, в не идемпотентной операции нет гарантии, что будет получено то же состояние ресурса.

основываясь на приведенном выше идемпотентном определении, мой подход к использованию метода HTTP PUT по сравнению с использованием метода HTTP POST для служб REST: Используйте метод HTTP PUT, когда:

The client includes all aspect of the resource including the unique identifier to uniquely identify the resource. Example: creating a new employee.
The client provides all the information for a resource to be able to modify that resource.This implies that the server side does not update any aspect of the resource (such as an update date).

В обоих случаи, эти операции могут выполняться несколько раз с одинаковыми результатами. То есть ресурс не будет изменен путем запроса операции более одного раза. Следовательно, истинная идемпотентная операция. Используйте метод HTTP POST, когда:

The server will provide some information concerning the newly created resource. For example, take a logging system. A new entry in the log will most likely have a numbering scheme which is determined on the server side. Upon creating a new log entry, the new sequence number will be determined by the server and not by the client.
On a modification of a resource, the server will provide such information as a resource state or an update date. Again in this case not all information was provided by the client and the resource will be changing from one modification request to the next. Hence a non idempotent operation.

вывод

не связывайте напрямую и не сопоставляйте операции CRUD с HTTP-методами для служб REST. Использование метода HTTP PUT против метода HTTP POST должно основываться на идемпотентном аспекте этой операции. То есть, если операция является идемпотентной, используйте метод HTTP PUT. Если операция не является идемпотентной, используйте метод HTTP POST.


исходный сервер может создать ресурс с этим URI

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

Как упоминалось в вашей цитате, вы используете PUT для создания нет ресурса, назначенного IRI, и вы все равно хотите создать ресурс. Например, PUT /users/123/password обычно заменяет старый пароль на новый, но вы можете использовать его для создания пароля, если он еще не существует (например, только что зарегистрированные пользователи или восстановление запрещенных пользователей).


читатели, новички в этой теме, будут поражены бесконечной дискуссией о том, что вы должны do, и относительное отсутствие уроков из опыта. Тот факт, что отдых "предпочтительнее" мыла, я полагаю, является уроком высокого уровня из опыта, но доброта, мы должны прогрессировать оттуда? Это 2016. Диссертация Роя была в 2000 году. Что мы разработали? Было весело? С ним было легко интегрироваться? Для поддержки? Будет ли он обрабатывать рост смартфонов и flaky mobile подключений?

по моему мнению, реальные сети ненадежны. Просит тайм-аут. Соединения сбрасываются. Сети отключаются на несколько часов или дней. Поезда отправляются в туннели с мобильными пользователями на борту. Для любого запроса (как иногда признается во всех этих обсуждениях) запрос может упасть в воду по пути, или ответ может упасть в воду на обратном пути. в этих условиях выдача запросов PUT, POST и DELETE непосредственно против основных ресурсы всегда казались мне немного грубыми и наивными.

HTTP ничего не делает для обеспечения надежного завершения запроса-ответа, и это просто прекрасно, потому что это правильно работа сетевых приложений. Разрабатывая такое приложение, вы можете прыгать через обручи, чтобы использовать PUT вместо POST, а затем еще обручи, чтобы дать определенный вид ошибки на сервере, если вы обнаружите дубликаты запросов. Возвращаясь к клиенту, вам нужно прыгать через обручи, чтобы интерпретировать эти ошибки, refetch, revalidate и repost.

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

сервер делает бизнес, возвращает ответ и сохраняет его против согласованного действия URI. Если что-то идет не так, клиент повторяет запрос (естественное поведение!), и если сервер уже видел его, он повторяет сохраненный ответ и не.

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

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

таким образом, многочисленные острые проблемы уходят. Повторные запросы вставки не будут создавать дубликатов, и мы не создаем реальный ресурс, пока не получим данные. (столбцы базы данных могут оставаться не-nullable). Повторные запросы на обновление не попадают в несовместимые состояния и не перезаписывают последующие изменения. Клиенты могут (re)fetch и seamlessy обрабатывать первоначально подтверждение для по какой причине (клиент разбился, ответ пропал без вести и т. д.).

последовательные запросы удаления могут видеть и обрабатывать исходное подтверждение, не нажимая ошибку 404. Если все займет больше времени, чем ожидалось, мы можем ответить условно, и у нас есть место, где клиент может проверить окончательный результат. Самая приятная часть этого шаблона-его свойство кунг-фу (Панда). Мы принимаем слабость, склонность для клиентов повторить запрос в любое время они не понимают ответ, и превратить его в сила : -)

прежде чем сказать мне, что это не успокаивает, пожалуйста, рассмотрите многочисленные способы, которыми соблюдаются принципы отдыха. Клиенты не создают url. API остается обнаруживаемым, хотя и с небольшим изменением семантики. Глаголы HTTP используются соответствующим образом. Если вы думаете, что это огромное изменение для реализации, я могу сказать вам по опыту, что это не так.

Если вы думаете, что у вас будет огромное количество данных для хранения, давайте talk volumes: типичное подтверждение обновления-это доля килобайта. HTTP в настоящее время дает вам минуту или две, чтобы окончательно ответить. Даже если вы храните действия только в течение недели, у клиентов есть достаточно шансов наверстать упущенное. Если у вас очень большие объемы, может потребоваться специальное хранилище значений ключей, совместимое с acid, или решение в памяти.


Я собираюсь приземлиться со следующим:

PUT относится к ресурсу, определяемому URI. В этом случае, вы обновляете его. Это часть трех глаголов, относящихся к ресурсам-удалить и получить, будучи двумя другими.

POST-это в основном сообщение свободной формы, значение которого определяется как "вне диапазона". Если сообщение можно интерпретировать как добавление ресурса в каталог, это будет нормально, но в основном вам нужно понять сообщение, которое вы отправка (разноска), чтобы узнать, что произойдет с ресурсом.


поскольку PUT, GET и DELETE относятся к ресурсу, они также по определению являются идемпотентными.

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

PUT не должен быть create; служба может ошибиться, если ресурс еще не создан, но в противном случае обновите его. Или наоборот - он может создавать ресурс, но не разрешать обновления. Единственное, что требуется от PUT, - это то, что он указывает на определенный ресурс, а его полезная нагрузка-это представление этого ресурса. Успешный PUT означает (исключая помехи), что GET будет извлекать тот же ресурс.


Edit: еще одна вещь -- A PUT может создавать, но если это так, то ID должен быть естественным ID -- он же адрес электронной почты. Таким образом, когда вы ставите дважды, второй put является обновлением первого. Это делает его идемпотентных.

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


семантика должна быть разной, в том ,что "PUT", например" GET", должен быть идемпотентным-то есть вы можете один и тот же точный запрос PUT несколько раз, и результат будет таким, как если бы вы выполнили его только один раз.

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

когда вы помещаете ресурс по определенному URL-адресу, происходит то, что он должен быть сохранен по этому URL-адресу или что-то в этом роде.

когда вы отправляете на ресурс по определенному URL-адресу, часто вы отправляете связанную часть информации по этому URL-адресу. Это означает, что ресурс по URL уже существует.

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

Что касается изменения свойств потока, вы можете сделать это с помощью PUT или POST. В принципе, используйте только "PUT", когда операция idempotent-в противном случае используйте POST.

обратите внимание, однако, что не все современные браузеры поддерживают http-глаголы, кроме GET или POST.


большую часть времени, вы будете использовать их так:

  • в должности ресурс в коллекцию
  • поставить ресурс, идентифицированный коллекцией/: id

например:

  • в должности / items
  • поставить / items / 1234

в обоих случаях, тело запроса содержит данные для ресурса, который будет создан или обновлен. Это должно быть очевидно из имен маршрутов, которые POST не является идемпотентными (если вы назовете его 3 раза, он создаст 3 объекта), но PUT является идемпотентным (если вы назовете его 3 раза, результат будет таким же). PUT часто используется для операции "upsert" (create или update), но вы всегда можете вернуть ошибку 404, если хотите использовать ее только для изменения.

обратите внимание, что POST "создает" новый элемент в коллекции и "заменяет" элемент по заданному URL-адресу, но очень распространенная практика использовать PUT для частичного модификации, то есть использовать его только для обновления существующих ресурсов и только изменять включенные поля в теле (игнорируя другие поля). Это технически неверно, если вы хотите быть REST-purist, PUT должен заменить весь ресурс, и вы должны использовать патч для частичного обновления. Мне лично все равно, насколько поведение ясно и последовательно во всех конечных точках API.

помните, REST-это набор соглашений и рекомендаций, чтобы ваш API был простым. Если вы в конечном итоге со сложной работой вокруг просто, чтобы проверить" RESTfull " поле, то вы побеждаете цель;)


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

давайте будем очень ясными и прямыми здесь. Если вы разработчик .NET, работающий с Web API, факты (из документации Microsoft API), http://www.asp.net/web-api/overview/creating-web-apis/creating-a-web-api-that-supports-crud-operations:

1. PUT = UPDATE (/api/products/id)
2. MCSD Exams 2014 -  UPDATE = PUT, there are **NO** multiple answers for that question period.

конечно, вы "можете" использовать "POST" для обновления, но просто следуйте соглашениям, изложенным для вас с вашей данной структурой. В моем случае это .NET / Web API, поэтому PUT для обновления нет дискуссии.

Я надеюсь, что это поможет любым разработчикам Microsoft, которые читают все комментарии со ссылками на веб-сайт Amazon и Sun/Java.


Если вы знакомы с операциями базы данных, есть

  1. выберите
  2. вставить
  3. обновление
  4. удалить
  5. Merge (обновить, если уже существует, иначе вставить)

Я использую PUT для слияния и обновления как операции и использовать POST для вставок.


на практике POST хорошо работает для создания ресурсов. URL-адрес вновь созданного ресурса должен быть возвращен в заголовке ответа местоположения. PUT должен использоваться для полного обновления ресурса. Пожалуйста, поймите, что это лучшие практики при разработке RESTful API. Спецификация HTTP как таковая не ограничивает использование PUT/POST несколькими ограничениями для создания / обновления ресурсов. Взгляните на http://techoctave.com/c7/posts/71-twitter-rest-api-dissected это обобщает передовую практику.


вот простое правило:

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

в должности to URL должен использоваться для обновления или создания ресурса, который находится на каком-либо другом ("подчиненном") URL-адресе или не локализуется через HTTP.


сообщение: использовать его для создания новых ресурсов. Это похоже на INSERT (оператор SQL)с автоматически увеличенным идентификатором. В части ответа он содержит новый сгенерированный идентификатор.

POST также используется для обновления записи.

PUT: использовать его для создания нового ресурса, но здесь я знаю ключ личности. Это похоже на INSERT (оператор SQL), где я заранее знаю ключ идентификации. В части ответа он отправляет ничего.

PUT также используется для обновления ресурса