ПОСТ против ПОЧТЫ в ОТДЫХЕ - PullRequest
4976 голосов
/ 10 марта 2009

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

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

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

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

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

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

Ответы [ 32 ]

14 голосов
/ 10 октября 2013

Кажется, всегда возникает путаница относительно того, когда использовать 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 для создания, в то время как в других случаях потребуется POST. Неоднозначность заключается в определении метода 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.

13 голосов
/ 16 января 2014

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

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

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

11 голосов
/ 25 сентября 2018

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

В POST методе вы можете отправлять параметры тела в form-data

В PUT методе вы должны отправлять параметры тела в x-www-form-urlencoded

Заголовок Content-Type:application/x-www-form-urlencoded

В соответствии с этим, вы не можете отправлять файлы или составные данные методом PUT

EDIT

Тип контента "application / x-www-form-urlencoded" неэффективен для отправки большого количества двоичных данных или текста, содержащего не-ASCII символы. Тип содержимого "multipart / form-data" должен быть используется для отправки форм, которые содержат файлы, данные не в формате ASCII и двоичные данные.

Что означает, если вы должны подать

файлы, данные не ASCII и двоичные данные

вы должны использовать POST метод

11 голосов
/ 22 октября 2013

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

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

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


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

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

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


Редактировать: Еще одна вещь - PUT может создавать, но если это происходит, то идентификатор должен быть естественным ID - AKA адрес электронной почты. Таким образом, когда вы PUT дважды, второй пут - это обновление первого. Это делает его идемпотентным .

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

9 голосов
/ 24 октября 2011

Семантика должна быть разной, в том смысле, что «PUT», как и «GET», считается идемпотентным - это означает, что вы можете один и тот же точный запрос PUT несколько раз, и результат будет таким, как если бы вы выполняли его только один раз ,

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

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

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

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

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

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

7 голосов
/ 21 июня 2017

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

  • POST ресурс в коллекции
  • PUT ресурс, определенный по коллекции /: id

Например:

  • POST / items
  • PUT / items / 1234

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

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

Помните, REST - это набор соглашений и руководств, позволяющих сделать ваш API простым. Если у вас сложный обходной путь только для того, чтобы установить флажок «RESTfull», значит, вы победили цель;)

7 голосов
/ 22 июля 2014

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

Давайте будем очень ясными и прямыми. Если вы - разработчик .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.

6 голосов
/ 12 декабря 2013

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

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

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

6 голосов
/ 30 июня 2016

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

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

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

5 голосов
/ 06 октября 2014

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

...