REST API с использованием POST вместо GET

предположим, что служба предлагает некоторую функциональность, которую я могу использовать следующим образом:

GET /service/function?param1=value1&param2=value2

правильно ли говорить, что я могу использовать его с запросом POST?

POST /service/function { param1 : value1, param2 : value2 }

являются ли эти два запроса одинаковыми? Могу ли я использовать второй вариант в любом случае или документация должна явно сказать, что я могу использовать запросы GET и POST?

6 ответов


вы не можете использовать API С помощью POST или GET если они не строятся для вызова с использованием этих методов отдельно. Например, если ваш API говорит

/service/function?param1=value1&param2=value2

осуществляется с помощью GET метод. Тогда вы не можете назвать его с помощью POST метод, если он не указан как POST метод его создателя. Если вы это сделаете, вы можете получить 405 Method not allowed статус.

в целом POST метод вам нужно отправить содержимое в теле с указанным форматом, который описан в content-type заголовок для ex. application/json для данных json.

и после этого тело запроса десериализуется на сервере. Поэтому вам нужно передать сериализованные данные от клиента, и это решает разработчик службы.

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


просто для обзора, REST имеет определенные свойства, которые разработчик должен следовать, чтобы сделать это RESTful:

что такое отдых?

согласно Википедии:

архитектурный стиль REST описывает следующие шесть ограничений приложенный к архитектуре, пока выходящ осуществление индивидуальные компоненты свободно конструировать:

  • клиент–сервер: серверы не связано с пользовательским интерфейсом или пользовательским состоянием, так что серверы могут быть проще и масштабируемы.
  • без гражданства: связь между клиентом и сервером дополнительно ограничена отсутствием контекста клиента, хранящегося на сервере между запросами.
  • Cacheable: ответы должны, неявно или явно, определять себя как кэшируемые или нет, чтобы предотвратить повторное использование клиентами устаревших или ненадлежащих данных в ответ на дальнейшие запросы.
  • многоуровневая система: клиент обычно не может сказать, подключен ли он непосредственно к конечному серверу или к посреднику по пути. Промежуточные серверы могут улучшить масштабируемость системы путем обеспечения балансировки нагрузки и предоставления общих кэшей.
  • код по требованию (опционально): серверы могут временно расширить или настроить функциональность клиента путем передачи исполняемого кода.
  • единый интерфейс: единый интерфейс между клиентами и серверами, обсуждаемый ниже, упрощает и разъединяет архитектуру, которая позволяет каждой части развиваться независимо. (т. е. HTTP GET, POST, PUT, PATCH, DELETE)

что должны делать глаголы

так что пользователь Даниил Vasallo проделал хорошую работу по изложению обязанностей этих методов в вопросе понимание REST: глаголы, коды ошибок и аутентификация:

при работе с URI коллекции, как:http://example.com/resources/

GET: список членов коллекции, в комплекте с их членом URIs для дальнейшей навигации. Например, перечислите все автомобили на продажу.

поставить: значение, определенное как " заменить всю коллекцию на другой коллекция."

сообщение: создайте новую запись в коллекции, для которой назначен идентификатор автоматически коллекцией. Созданный ID обычно включается как часть данных, возвращенных этой операцией.

удалить: значение, определенное как "удалить всю коллекцию".

Итак, чтобы ответить на ваш вопрос:

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

эти два запроса одинаковы? Могу ли я использовать второй вариант в любом случае или документация должна явно сказать, что я могу использовать запросы GET и POST?

если вы пишете простой старый вызов RPC API, они могут быть технически взаимозаменяемыми, пока сервер обработки не отличается между обоими вызовами. Однако, чтобы вызов был RESTful, вызов конечной точки через GET метод должен иметь четкую функциональность (который должен получить ресурс (ы)) из POST метод (который должен создать новые ресурсы).

Примечание: есть некоторые дебаты там о том, или нет POST также должно быть разрешено использовать для обновления ресурсов... хотя я не комментирую это, я просто говорю вам, что у некоторых людей есть проблема с этим моментом.


Я использую Post body для чего-либо нетривиального и бизнес-приложений по следующим причинам:

  1. безопасность-если мы используем GET со строками запроса и https, строки запроса могут быть сохранены в журналах сервера и перенаправлены как реферальные ссылки. Оба они теперь доступны администраторам сервера / сети и следующему домену, в который пользователь вошел после выхода из приложения. Поэтому, если мы отправим запрос, содержащий конфиденциальные данные PII, такие как имя клиента, это может быть нежелательно.
  2. URL-адрес максимальная длина - не большая проблема, но некоторые браузеры имеют ограничение на длину. Так что если у нас есть несколько элементов в наш адрес запрос, пейджинг, поля для возврата, и т. д....
  3. Post по умолчанию не является кэшем. Некоторые говорят, что кэширование желательно; однако, как часто тот же самый набор критериев поиска для этого точного объекта для этого точного клиента будет происходить до истечения времени ожидания кэша в любом случае?

кстати, я также помещаю поля для возврата в мое тело поста, поскольку я не могу этого хотеть выставьте мои имена полей. Безопасность подобна луковице; много слоев и заставляет нас плакать!


подумайте об этом. Когда ваш клиент делает запрос GET к URI X, он говорит серверу: "я хочу представление ресурса, расположенного в X, и эта операция не должна ничего менять на сервере."Запрос PUT говорит:"Я хочу, чтобы вы заменили любой ресурс, расположенный в X, на новый объект, который я даю вам в теле этого запроса". Запрос на удаление говорит:"Я хочу, чтобы вы удалили все, что является ресурсом, расположенным на X". Патч говорит: "Я отдаю вы это diff, и вы должны попытаться применить его к ресурсу на X и сказать мне, если это удастся."Но сообщение говорит:" Я отправляю вам эти данные, подчиненные ресурсу на X, и у нас есть предыдущее соглашение о том, что вы должны с ним делать."

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

REST полагается на стандартизированное поведение из базового протокола и POST-это именно метод, используемый для действия, которое не стандартизировано. Результат запросов GET, PUT и DELETE четко определен в стандарте, но POST-нет. Результат поста подчиняется серверу, поэтому, если не задокументировано, что вы можете использовать POST для чего-то, вы должны предположить, что не можете.


в REST каждый http-глагол имеет свое место и значение.

например,

  • GET-это получить " ресурс (ы)", на который указывается в URL-адресе.

  • POST-это указание бэкэнду "создать" ресурс "типа", указанного в URL-адресе. Операцию POST можно дополнить параметрами или дополнительными данными в теле вызова POST.

в вашем случае, так как вы заинтересованы в "получение" информации с помощью запроса, таким образом, это должна быть операция GET вместо операции POST.

этой wiki может помочь для дальнейшего выяснения дела.

надеюсь, что это поможет!


приятно, что REST привносит смысл в HTTP-глаголы (как они определены), но я предпочитаю соглашаться со Скоттом пил.

вот также пункт из расширенного объяснения WIKI на POST запрос:

бывают случаи, когда HTTP GET менее подходит даже для извлечения данных. Примером этого является то, когда в URL-адресе необходимо указать большое количество данных. Браузеры и веб-серверы могут иметь ограничения на длину URL-адреса, которые они обрабатывают без усечения или ошибки. Процентное кодирование зарезервированных символов в URL-адресах и строках запросов может значительно увеличить их длину, и, хотя Apache HTTP Server может обрабатывать до 4000 символов в URL-адресе, [5] Microsoft Internet Explorer ограничен 2048 символами в любом URL-адресе.[6] точно так же HTTP GET не должен использоваться там, где конфиденциальная информация, такая как имена пользователей и пароли, должна быть отправлена вместе с другими данными для завершения запроса. Даже если используется HTTPS, предотвращение данные, перехваченные в пути, история браузера и журналы веб-сервера, вероятно, будут содержать полный URL-адрес в открытом тексте, который может быть выставлен, если любая система взломана. В этих случаях следует использовать HTTP POST.[7]

Я мог бы только предложить команде REST рассмотреть более безопасное использование протокола HTTP, чтобы избежать борьбы потребителей с небезопасной "хорошей практикой".