Зачем использовать методы HTTP PUT и DELETE вместо POST? - PullRequest
24 голосов
/ 24 мая 2009
new_story GET     /story/new(.:format)  {:action=>"new", :controller=>"stories"}
edit_story GET     /story/edit(.:format) {:action=>"edit", :controller=>"stories"}
     story GET     /story(.:format)      {:action=>"show", :controller=>"stories"}
           PUT     /story(.:format)      {:action=>"update", :controller=>"stories"}
           DELETE  /story(.:format)      {:action=>"destroy", :controller=>"stories"}
           POST    /story(.:format)      {:action=>"create", :controller=>"stories"}

В веб-работе с другими технологиями я использовал только методы GET и POST. Но с RESTful-маршрутами в Rails, по умолчанию методы PUT и DELETE используются для действий обновления и уничтожения. В чем преимущество или необходимость использования PUT и DELETE? Я предполагаю, что эти методы - просто еще один способ сделать POST - но почему бы просто не придерживаться POST?

Ответы [ 4 ]

51 голосов
/ 24 мая 2009

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

POST   => create a new object
DELETE => delete an object
PUT    => modify an object
GET    => view an object

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

Однако на практике большинство браузеров поддерживают только HTTP GET и POST. Rails использует некоторую «хитрость» в формах HTML, чтобы действовать так, как если бы был отправлен запрос PUT или DELETE, хотя Rails все еще использует GET или POST для этих методов. (Это объясняет, почему вы не могли использовать DELETE или PUT на других платформах.)

9 голосов
/ 26 мая 2009

Вот раздел «методы» спецификации HTTP 1.1 ; он определяет множество методов, и все они имеют разные преимущества и недостатки. POST является наиболее гибким, но компромиссы многочисленны: он не кешируется (поэтому остальная часть интернета не может помочь вам масштабироваться), он не безопасен и не идемпотентен, поэтому клиент не может просто повторно отправить его ошибка, и уже не ясно, что именно вы пытаетесь достичь (потому что это очень гибко). Я уверен, что есть и другие, но этого должно быть достаточно. Учитывая все это, если спецификация HTTP определяет метод, который делает именно то, что вы хотите, чтобы ваш запрос, нет никакой причины отправлять POST вместо.

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

Кстати, отображение, которое дал @mipadi, является стандартным отображением, но оно не единственно допустимое. Amazon S3, например, использует PUT для создания ресурсов. Единственная причина использования POST заключается в том, что клиент не обладает достаточными знаниями для создания ресурса, например, вы подкрепляете свои ресурсы реляционной базой данных и используете искусственные суррогатные ключи.

7 голосов
/ 24 мая 2009

Это было бы все равно, что спрашивать, зачем «удалять» файл, когда вы можете просто установить его содержимое равным нулю байтов, а файловая система будет воспринимать это как удаление. HTTP всегда поддерживает глаголы, отличные от GET / POST, но эволюция SOAP немного искажает первоначальное значение этих глаголов. REST - это более простой, возвращающийся к основам подход, который использует глаголы так, как они были предназначены, вместо того, чтобы изобретать какую-то новую концепцию глаголов внутри полезной нагрузки.

3 голосов
/ 10 ноября 2017

Я просто хотел что-то добавить к принятому ответу, потому что его определение http verbs неверно. Все они имеют спецификацию, которой «следует» следовать, и вы можете создавать / обновлять / удалять с несколькими http verbs на основе спецификаций.

Я собираюсь выделить некоторые важные биты в RFC 2616 от W3

Я собираюсь начать с PUT, потому что, по моему мнению, это наиболее запутанно.

  • PUT is used for both create/update PUT updates by completely replacing the resource on the server with the resource sent in the request

Например

Вы делаете этот вызов на мой API

PUT        /api/person
{
     Name: John,
     email: jdoe@hra.com
}

мой сервер имеет этот ресурс на сервере

{
     Name: Jane,
     email: jdoe@hra.com
}

Теперь мой существующий ресурс полностью заменен тем, что вы отправили, и это то, что у меня есть на моем сервере.

{
     Name: John,
     email: jdoe@hra.com
}

Так что если вы PUT и отправите только электронное письмо в теле

PUT        /api/person
{
     email: jdoe@hra.com
}

Мой сервер полностью заменит сущность

{
     Name: Jane,
     email: jdoe@hra.com
}

С

{
     email: jdoe@hra.com
}

И Имя исчезнет. Частичные обновления предназначены для PATCH, но я все равно использую POST.

  • One of the main reasons why we create/update with put is because it is idempotent.

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

Пример * +1049 *

Предположим, я PUT файл в api/file, если сервер-источник не найдет этот файл, он его создаст. Если он найдет файл, он полностью заменит старый файл тем, который я отправил. Это гарантирует, что один файл когда-либо будет создан и обновлен. Если файл не существует, и вы вызываете PUT 5 раз, то при первом создании файла он затем заменяется другим файлом с тем, что вы отправляете. над. Если вы позвоните POST 5 раз, чтобы создать его, будет создано 5 файлов.

  • You PUT to that exact URI. If you don't you have to send a 301 (Moved Permanently) to the user and allow then make a choice whether or not to redirect the request. Most times the server you PUT to usually hosts the resource and takes care of updating it

Это основные моменты, когда использовать PUT

Что касается POST

  • You can also create/update and then some...

Как я упоминал выше, есть несколько ключевых отличий.

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

А как насчет Delete Почему бы мне просто не POST?

Когда вы DELETE, сервер НЕ ДОЛЖЕН отвечать success , если вы не удалите ресурс или не переместите его в недоступное место во время отправки ответа .

Почему это важно? Что если вы позвоните по номеру DELETE, но ресурс должен пройти «УТВЕРЖДЕНИЕ» перед удалением? Если удаление может быть отклонено, вы не можете отправить успешный код ошибки, и если вы действительно следуете основным спецификациям, это сбивает с толку вызывающего. Просто пример, я уверен, что вы можете думать о многих других.

Я только что выделил некоторые основные моменты, когда следует использовать общий Http verbs

...