Я разрабатываю API для работы с HTTP, и мне интересно, если использовать команду HTTP POST, но только с параметрами URL-запроса и без тела запроса, это хороший путь.
Соображения:
- «Хороший веб-дизайн» требует отправки неидемпотентных действий через POST. Это неидемпотентное действие.
- Это приложение легче разрабатывать и отлаживать, когда параметры запроса присутствуют в URL.
- API не предназначен для широкого использования.
- Кажется, что выполнение запроса POST без тела потребует немного больше работы, например,
Content-Length: 0
заголовок должен быть явно добавлен. - Мне также кажется, что POST без тела немного противоречит ожиданиям большинства разработчиков и HTTP-фреймворков.
Есть ли еще какие-нибудь подводные камни или преимущества для отправки параметров запроса POST через URL-запрос, а не тело запроса?
Изменить: Причина, по которой это рассматривается, заключается в том, что операции не являются идемпотентными и имеют побочные эффекты, кроме поиска. Смотрите спецификации HTTP :
В частности, было установлено, что методы GET и HEAD НЕ ДОЛЖНЫ иметь значение выполнения действия, отличного от извлечения. Эти методы следует считать «безопасными». Это позволяет пользовательским агентам представлять другие методы, такие как POST, PUT и DELETE, особым образом, чтобы пользователь знал о том, что запрашивается небезопасное действие.
...
Методы также могут иметь свойство "идемпотентности", заключающееся в том, что (кроме ошибок с ошибками или истечением срока действия) побочные эффекты от N> 0 идентичных запросов такие же, как и для одного запроса. Методы GET, HEAD, PUT и DELETE разделяют это свойство. Кроме того, методы OPTIONS и TRACE НЕ ДОЛЖНЫ иметь побочных эффектов, и поэтому являются по своей сути идемпотентными.
Ответы:
Если ваше действие не идемпотентно, то вы ДОЛЖНЫ использовать
POST
. Если вы этого не сделаете, вы просто напрашиваетесь на неприятности в будущем.GET
,PUT
ИDELETE
методы требуется , чтобы быть идемпотентными. Представьте, что произойдет в вашем приложении, если клиент будет предварительно извлекать все возможныеGET
запросы вашего сервиса - если это вызовет побочные эффекты, видимые для клиента, то что-то не так.Я согласен, что отправка
POST
со строкой запроса, но без тела, кажется странной, но я думаю, что это может быть уместно в некоторых ситуациях.Думайте о части запроса URL как о команде ресурса, чтобы ограничить область действия текущего запроса. Как правило, строки запроса используются для сортировки или фильтрации
GET
запроса (например?page=1&sort=title
), но я предполагаю, что имеет смыслPOST
также ограничивать область действия (возможно, как?action=delete&id=5
).источник
/action?response_format=json
)Все правы: придерживайтесь POST для неидемпотентных запросов.
Как насчет использования строки запроса URI и содержимого запроса? Ну, это действительный HTTP (см. Примечание 1), так почему бы и нет ?!
Это также совершенно логично: URL-адреса, включая часть строки запроса, предназначены для поиска ресурсов. Принимая во внимание, что глаголы метода HTTP (POST - и его необязательное содержимое запроса) предназначены для указания действий или действий с ресурсами. Это должны быть ортогональные проблемы. (Но они не являются красиво ортогональными проблемами для особого случая ContentType = application / x-www-form-urlencoded, см. Примечание 2 ниже.)
Примечание 1: спецификация HTTP (1.1) не устанавливает, что параметры и содержимое запроса являются взаимоисключающими для HTTP-сервера, который принимает запросы POST или PUT. Таким образом, любой сервер может принять оба варианта. То есть, если вы пишете сервер, ничто не мешает вам принять и то и другое (кроме, может быть, негибкой структуры). Обычно сервер может интерпретировать строки запроса в соответствии с любыми правилами. Он может даже интерпретировать их с помощью условной логики, которая ссылается и на другие заголовки, такие как Content-Type, что приводит к примечанию 2:
Примечание 2: если веб-браузер является основным способом доступа пользователей к вашему веб-приложению, а application / x-www-form-urlencoded является типом контента, который они публикуют, тогда вы должны следовать правилам для этого типа контента. А правила для application / x-www-form-urlencoded гораздо более специфичны (и, честно говоря, необычны): в этом случае вы должны интерпретировать URI как набор параметров, а не местоположение ресурса. [Это та же самая полезность, которую поднял Powerlord; что может быть трудно использовать веб-формы для размещения контента на вашем сервере. Просто объяснил немного по-другому.]
Примечание 3: для чего изначально нужны строки запроса? RFC 3986 определяет строки HTTP-запроса как часть URI, которая работает как неиерархический способ поиска ресурса.
Если читатели, задающие этот вопрос, захотят спросить, что такое хорошая архитектура RESTful: шаблон архитектуры RESTful не требует, чтобы схемы URI работали определенным образом. Архитектура RESTful связана с другими свойствами системы, такими как кэшируемость ресурсов, структура самих ресурсов (их поведение, возможности и представления), а также удовлетворяется ли идемпотентность. Или, другими словами, достижение дизайна, который очень совместим с протоколом HTTP и его набором глаголов метода HTTP. :-) (Другими словами, RESTful архитектура не очень presciptive с тем, как ресурсы расположены .)
Последнее замечание: иногда параметры запроса используются для других целей, которые не являются ни локализацией ресурсов, ни кодированием контента. Вы когда-нибудь видели параметр запроса, такой как «PUT = true» или «POST = true»? Это обходные пути для браузеров, которые не позволяют использовать методы PUT и POST. Хотя такие параметры рассматриваются как часть строки URL запроса (на проводе), я считаю , что они не являются частью запроса в URL-адресе в духе .
источник
Вы хотите причины? Вот один из них:
Веб-форму нельзя использовать для отправки запроса на страницу, которая использует сочетание GET и POST. Если вы установите метод формы GET, все параметры будут в строке запроса. Если вы установите метод формы POST, все параметры будут в теле запроса.
Источник: стандарт HTML 4.01, раздел 17.13.
источник
method
POST, нет упоминания об изменении URI в формеaction
. И любой URI, конечно, может уже содержать часть строки запроса./Books?bookCode=1234
, Веб-сервер получит переменные формы POST и строку запроса.С программной точки зрения для клиента он упаковывает параметры и добавляет их в URL и проводит POST против GET. На стороне сервера он оценивает входящие параметры из строки запроса вместо отправленных байтов. По сути, это стирка.
Возможные преимущества / недостатки могут быть связаны с тем, как конкретные клиентские платформы работают с процедурами POST и GET в их сетевом стеке, а также с тем, как веб-сервер обрабатывает эти запросы. В зависимости от вашей реализации, один подход может быть более эффективным, чем другой. Знание этого будет направлять ваше решение здесь.
Тем не менее, с точки зрения программиста, я предпочитаю разрешить либо POST со всеми параметрами в теле, либо GET со всеми параметрами в URL, и явно игнорировать параметры URL при любом запросе POST. Это позволяет избежать путаницы.
источник
Я думаю, что все еще может быть довольно RESTful иметь аргументы запроса, которые идентифицируют ресурс в URL, сохраняя полезную нагрузку контента, ограниченную телом POST. Казалось бы, это разделяет соображения "Что я посылаю?" против "Кому я посылаю это?"
источник
В лагере REST есть несколько руководящих принципов, которые мы можем использовать для стандартизации использования HTTP-глаголов. Это полезно при создании RESTful API, как вы делаете.
В двух словах: GET должен быть только для чтения, т.е. не должен влиять на состояние сервера. POST используется для создания ресурса на сервере. PUT используется для обновления или создания ресурса. DELETE используется для удаления ресурса.
Другими словами, если ваше действие API изменяет состояние сервера, REST советует нам использовать POST / PUT / DELETE, но не GET.
Пользовательские агенты обычно понимают, что выполнение нескольких POST - это плохо, и предупреждают об этом, потому что цель POST - изменить состояние сервера (например, оплатить товары при оформлении заказа), и вы, вероятно, не хотите делать это дважды!
Сравните с GET, который вы можете делать часто, как вам нравится (идемпотент).
источник
Я согласен - возможно, безопаснее использовать запрос GET, если вы просто передаете данные в URL, а не в теле. Смотрите этот похожий вопрос для некоторых дополнительных взглядов на всю концепцию POST + GET.
источник