PUT против POST в REST.

http rest post put


В соответствии со спецификацией HTTP/1.1:

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

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

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

То есть PUT используется для создания или замены .

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




Answer 1 Brian R. Bondy


Overall:

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

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

Можно использовать оба варианта, поэтому какой из них мне следует использовать в моем RESTful-дизайне:

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

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

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

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

Пример:

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

POST:

Используется для модификации и обновления ресурса

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

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

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

Если URL еще не создан, вам не следует использовать POST для его создания при указании имени. Это должно привести к ошибке «ресурс не найден», поскольку <new_question> еще не существует. <new_question> вы должны поместить ресурс <new_question> на сервер.

Хотя вы можете сделать что-то подобное,чтобы создать ресурсы,используя POST:

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

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

PUT:

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

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

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

Чтобы перезаписать существующий ресурс:

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

Кроме того, и немного более кратко, RFC 7231 Section 4.3.4 PUT состояния (выделение добавлено),

4.3.4. СТАВИТЬ

Метод PUT запрашивает, чтобы состояние целевого ресурса было created или replaced состоянием, определенным представлением, заключенным в полезную нагрузку сообщения запроса.




Answer 2 Cheeso


В сети можно найти утверждения,в которых говорится.

И это тоже не совсем верно.


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

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

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


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

so:

POST /expense-report

or:

PUT  /expense-report/10929



Answer 3 Nigel Thorne


  • POST to URL создает дочерний ресурс на URL-адресе, определенном сервером .
  • PUT to URL создает / заменяет ресурс полностью по URL- адресу, указанному клиентом .
  • PATCH to URL обновляет часть ресурса по указанному клиенту URL.

Соответствующая спецификация для PUT и POST - RFC 2616 §9.5ff.

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

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

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

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

RFC читает вот так:

Фундаментальное различие между ПОСТ и ПУТ-запросами отражено в различном значении Request-URI.URI в POST запросе идентифицирует ресурс,который будет обрабатывать вложенный объект.Этот ресурс может быть процессом,принимающим данные,шлюзом к какому-либо другому протоколу или отдельной сущностью,которая принимает аннотации.В отличие от этого,URI в PUT запросе идентифицирует сущность,заключенную в запрос-пользовательский агент знает,для чего предназначен URI,и сервер НЕ ДОЛЖЕН пытаться применить запрос к какому-либо другому ресурсу.Если сервер хочет,чтобы запрос был применен к другому URI,

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

Обновление 2018 : есть случай, который можно избежать, чтобы избежать PUT. Смотрите "ОТДЫХ без ПУТА"

Идея «REST без PUT» заключается в том, что потребители вынуждены публиковать новые «несущественные» ресурсы запросов. Как обсуждалось ранее, изменение почтового адреса клиента - это POST на новый ресурс «ChangeOfAddress», а не PUT ресурса «Customer» с другим значением поля почтового адреса.

взято из REST API Design - Моделирование ресурсов Пракашем Субраманиамом из Thoughtworks

Это заставляет API избегать проблем с переходом к другому состоянию при обновлении нескольких клиентов на одном ресурсе,и более хорошо сочетается с источниками событий и CQRS.Когда работа выполняется асинхронно,POSTing преобразование и ожидание его применения кажется уместным.




Answer 4 7hi4g0


Summary:

Create:

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

PUT

Создает THE новый ресурс с newResourceId в качестве идентификатора, в соответствии с / ресурсов URI или сбора .

PUT /resources/<newResourceId> HTTP/1.1 

POST

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

POST /resources HTTP/1.1

Update:

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

PUT

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

PUT /resources/<existingResourceId> HTTP/1.1

Explanation:

При работе с REST и URI , как правило, у вас есть общие на левый и конкретном по праву . В дженерики , как правило , называют коллекции и более конкретные детали можно назвать ресурс . Обратите внимание, что ресурс может содержать коллекцию .

Examples:

<- универсальный - специфичный ->

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

Вы сообщаете серверу об обновлении или создаете, если он не существует, ресурс john в коллекции пользователей .

Spec:

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

POST

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

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

PUT

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

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

Reference:




Answer 5 Alexander Torstling


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

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

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

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

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

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