Требуются/ожидаются запросы PUT и POST для тела запроса?
Я пишу RESTful api, и я думаю о процессе создания пользователем ключа. У меня есть следующие возможности:
- GET запрос
/new/<keyname>
- хотя это очень просто, я думаю, что не буду использовать это, потому что я слышал, что GET предназначен для получения и/или информации о листинге;
- Запрос POST на
/<keyname>
- Мне показалось, что это легко и просто, но не передает никаких данных в тело запроса. Могу ли я это сделать так? Это странно?
- Запрос POST на
/keys
, проходящий в теле запроса "keyname=SomeKey"
- Правильно ли это?
Я смотрел этот API от радостного и во всех своих запросах PUT и POST они передавали некоторые данные в теле запроса. Ожидается ли это? Действительно ли неверно не требовать тело запроса в запросе PUT и POST?
Ответы
Ответ 1
Я задал этот вопрос в Http-WG. Это был самый точный ответ, который я получил http://lists.w3.org/Archives/Public/ietf-http-wg/2010JulSep/0276.html
Таким образом, POST не требует тела. Я бы ожидал, что такое же оправдание может быть применено к PUT.
Ответ 2
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 обновляется. Я могу представить создание пустого объекта (возможно, заполнителя для будущей информации), но я не думаю, что много пользы от пустого обновления.
Ответ 3
Это не обязательно. Вы можете отправить запрос POST/PUT без тела и вместо этого использовать параметры строки запроса. Но будьте осторожны, если ваши параметры содержат символы, которые не являются действительными HTTP, вам придется их кодировать.
Например, если вам нужно POST 'hello world' до конечной точки, вы должны сделать так, чтобы это выглядело следующим образом: http://api.com?param=hello%20world
Ответ 4
Вероятно, лучший способ - это ваш третий вариант: POST до /keys
с keyname=SomeKey
.
Здесь почему: вы можете добавить еще одну функцию в свой API, например create_new_user
. Тогда было бы трудно сказать разницу между пользователем, пытающимся выполнить POST ключ с именем create_new_user
и пользователем, пытающимся использовать функцию create_new_user
.
Вы правильно говорите, что не должны использовать GET для выполнения этой операции как операции GET "НЕ ДОЛЖНО иметь значение принятия действия кроме поиска" (RFC 2616).
Ответ 5
Чтобы ответить на ваш вопрос в одной строке. Да, ожидается, что Body/Content будет иметь тело, но он не требуется (обязательно).
Ответ 6
Согласно okHttp3 (HTTP-библиотека для android): следующие методы нуждаются в теле: POST, PUT, PATCH, PROPPATCH (WebDAV) и REPORT (источник). Он даже сработает, если вы попытаетесь выполнить запрос с данными методами без тела.