Требуются ли / должны ли запросы PUT и POST иметь тело запроса? - PullRequest
23 голосов
/ 06 сентября 2011

Я пишу API-интерфейс RESTful, и сейчас я думаю о том, как пользователь создает ключ.У меня есть следующие возможности:

  • запрос GET на /new/<keyname> - хотя это очень просто, я думаю, что не буду использовать это, потому что я слышал, что GET предназначен для получения и / или перечисления информации;*
  • POST-запрос к /<keyname> - мне это показалось достаточно простым и легким, но не передает никаких данных в тело запроса.Могу ли я сделать это таким образом?Это странно?
  • POST-запрос к /keys, передаваемый в теле запроса "keyname=SomeKey" - Это правильный путь?

Я посмотрел на этот API от joyent и во всех своих запросах PUT и POST они передают некоторые данные в тело запроса.Это ожидается?Действительно ли неправильно не требовать тела запроса в запросах PUT и POST?

Ответы [ 6 ]

14 голосов
/ 07 сентября 2011

Я задал этот вопрос по Http-WG. Это был самый точный ответ, который я получил http://lists.w3.org/Archives/Public/ietf-http-wg/2010JulSep/0276.html

Таким образом, POST не требует тела. Я ожидаю, что такое же обоснование может быть применено к PUT.

6 голосов
/ 06 сентября 2011

RFC2616 является базовым RFC для HTTP 1.1

В наиболее общей форме HTTP-сообщение является следующим (обратите внимание на необязательное тело):

generic-message = start-line
                  *(message-header CRLF)
                  CRLF
                  [ message-body ]
start-line      = Request-Line | Status-Line

Чтение далее дает следующее:

9.5 POST

   The POST method is used to request that the origin server accept the
   entity enclosed in the request as a new subordinate of the resource
   identified by the Request-URI in the Request-Line. ...

и

9.6 PUT

   The PUT method requests that the enclosed entity be stored under the
   supplied Request-URI. ...

   The fundamental difference between the POST and PUT requests is
   reflected in the different meaning of the Request-URI. The URI in a
   POST request identifies the resource that will handle the enclosed
   entity. That resource might be a data-accepting process, a gateway to
   some other protocol, or a separate entity that accepts annotations.
   In contrast, the URI in a PUT request identifies the entity enclosed
   with the request -- the user agent knows what URI is intended and the
   server MUST NOT attempt to apply the request to some other resource.

И POST, и PUT включают фразу , заключенную в запросе .

Исходя из моего прочтения, я считаю, что для POST и PUT желательно тело (как я знаю, ненормативное описание).

В контексте REST, POST - это создание, PUT - это обновление.Я могу представить себе создание пустого объекта (возможно, заполнителя для будущей информации), но я не представляю себе большого применения пустого обновления.

0 голосов
/ 09 июля 2019

Не требуется. Вы можете отправить запрос POST / PUT без тела и вместо этого использовать параметры строки запроса. Но будьте осторожны, если ваши параметры содержат символы, которые не являются действительными HTTP, вам придется их кодировать.

Например, если вам нужно POST 'hello world' к конечной точке, вы должны сделать так, чтобы это выглядело так: http://api.com? Param = hello% 20world

0 голосов
/ 10 марта 2017

Согласно okHttp3 (HTTP-библиотека для Android): следующие методы нуждаются в теле: POST, PUT, PATCH, PROPPATCH (WebDAV) и REPORT ( source ). Он даже падает, если вы попытаетесь выполнить запрос с указанными методами без тела.

0 голосов
/ 01 июня 2015

Чтобы ответить на ваш вопрос в одну строку. Да, ожидается, что в теле будет содержаться текст / содержание, но это не обязательно (обязательно).

0 голосов
/ 06 сентября 2011

Вероятно, лучшим вариантом является третий вариант: POST на /keys с keyname=SomeKey.

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

Вы правильно сказали, что не должны использоватьGET выполнить эту операцию как операцию GET «НЕ ДОЛЖНО иметь значение выполнение действия, отличного от извлечения».(RFC 2616) .

...