REST API - зачем использовать PUT DELETE POST GET? - PullRequest
148 голосов
/ 01 января 2011

Итак, я просматривал некоторые статьи по созданию REST API. И некоторые из них предлагают использовать все типы HTTP-запросов: например, PUT DELETE POST GET. Например, мы создали бы index.php и напишем API следующим образом:

$method = $_SERVER['REQUEST_METHOD'];
$request = split("/", substr(@$_SERVER['PATH_INFO'], 1));

switch ($method) {
  case 'PUT':
    ....some put action.... 
    break;
  case 'POST':
    ....some post action.... 
    break;
  case 'GET':
    ....some get action.... 
    break;
  case 'DELETE':
    ....some delete action.... 
    break;
}

ОК, предоставлено - я пока мало знаю о веб-сервисах. Но разве не было бы проще просто принять JSON объект через обычный POST или GET (который будет содержать имя метода и все параметры), а затем ответить также в JSON. Мы можем легко сериализовать / десериализовать через PHP json_encode() и json_decode() и делать с этими данными все, что захотим, без необходимости работать с разными методами HTTP-запроса.

Я что-то упустил?

ОБНОВЛЕНИЕ 1:

Хорошо - после изучения различных API и изучения XML-RPC , JSON-RPC , SOAP , REST Я пришел к выводу, что этот тип API является надежным. На самом деле обмен стеками в значительной степени использует этот подход на своих сайтах, и я думаю, что эти люди знают, что делают Stack Exchange API .

Ответы [ 9 ]

194 голосов
/ 01 января 2011

Идея RE презентационного S tate T не заключается в том, чтобы получить доступ к данным самым простым способом.

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

REST - это методология значимого доступа к данным. Когда вы видите запрос в REST, он должен немедленно следить за тем, что происходит с данными.

Например:

GET: /cars/make/chevrolet

, вероятно, вернет список шевроле машин. Хороший API REST может даже включать некоторые параметры вывода в строку запроса, такие как ?output=json или ?output=html, что позволит автору доступа решать, в каком формате должна быть закодирована информация.

Подумав, как разумно включить типизацию данных в REST API, я пришел к выводу, что лучший способ явно указать тип данных - это уже существующее расширение файла, такое как .js, .json, .html или .xml. Отсутствующее расширение файла будет по умолчанию в любом формате по умолчанию (например, JSON); расширение файла, которое не поддерживается, может вернуть 501 Not Implemented код состояния .

Другой пример:

POST: /cars/
{ make:chevrolet, model:malibu, colors:[red, green, blue, grey] }

, скорее всего, создаст новый шевроле малибу в БД со связанными цветами. Я говорю , вероятно , поскольку REST API не должен быть напрямую связан со структурой базы данных. Это просто маскирующий интерфейс, обеспечивающий защиту истинных данных (представьте, что это средства доступа и мутаторы для структуры базы данных).

Теперь нам нужно перейти к вопросу идемпотентности . Обычно REST реализует CRUD по HTTP. HTTP использует GET, PUT, POST и DELETE для запросов.

Очень упрощенная реализация REST может использовать следующее отображение CRUD:

Create -> Post
Read   -> Get
Update -> Put
Delete -> Delete

В этой реализации есть проблема: публикация определяется как неидемпотентный метод. Это означает, что последующие вызовы одного и того же метода Post приведут к различным состояниям сервера. Получить, положить и удалить, идемпотентны; это означает, что вызов их несколько раз должен привести к одинаковому состоянию сервера.

Это означает, что запрос, такой как:

Delete: /cars/oldest

может быть реализовано как:

Post: /cars/oldest?action=delete

В то время как

Delete: /cars/id/123456

приведет к тому же состоянию сервера, если вы вызовете его один раз или 1000 раз.

Лучшим способом обработки удаления элемента oldest будет запрос:

Get: /cars/oldest

и используйте ID из полученных данных, чтобы сделать запрос delete:

Delete: /cars/id/[oldest id]

Проблема с этим методом может быть связана с добавлением другого элемента /cars между запросом /oldest и выдачей delete.

38 голосов
/ 01 января 2011

Это вопрос безопасности и ремонтопригодности.

безопасные методы

По возможности, вы должны использовать «безопасные» (однонаправленные) методы, такие как GET и HEAD, чтобы ограничить потенциальную уязвимость.

идемпотентные методы

По возможности, вы должны использовать «идемпотентные» методы, такие как GET, HEAD, PUT и DELETE, которые не могут иметь побочных эффектов и поэтому менее подвержены ошибкам / их легче контролировать.

Источник

24 голосов
/ 21 января 2012

Короче говоря, REST подчеркивает существительные над глаголами. Поскольку ваш API становится более сложным, вы добавляете больше вещей, чем команд.

9 голосов
/ 01 января 2011

Вы спросили :

Не было бы проще просто принять объект JSON через обычный $ _POST, а затем ответить и в JSON

Из Википедии на ОТДЫХ :

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

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

Настраиваемые протоколы данных (даже если они построены поверх стандартных, таких как SOAP или JSON) не рекомендуется и должны быть сведены к минимуму, чтобы наилучшим образом соответствовать идеологии REST.

SOAP RPC через HTTP, с другой стороны, рекомендует каждому разработчику приложения определить новый и произвольный словарь существительных и глаголов (например, getUsers (), savePurchaseOrder (...)), обычно накладываемых на HTTP 'POST Глагол Это не учитывает многие из существующих возможностей HTTP, таких как аутентификация, кэширование и согласование типов контента, и может привести к тому, что разработчик приложения заново изобретет многие из этих функций в новом словаре.

Фактические объекты, с которыми вы работаете, могут быть в любом формате. Идея состоит в том, чтобы повторно использовать как можно больше HTTP, чтобы представить ваши операции, которые пользователь хочет выполнить над этим ресурсом (запросы, управление состоянием / мутация, удаление).

Вы спросили :

Я что-то упустил?

Намного больше нужно знать о REST и синтаксисе URI / самих HTTP-глаголах. Например, некоторые глаголы являются идемпотентными, другие - нет. Я не видел ничего об этом в вашем вопросе, поэтому я не стал пытаться погрузиться в это. Другие ответы и Википедия содержат много полезной информации.

Кроме того, многое можно узнать о различных сетевых технологиях, построенных на основе HTTP, которыми вы можете воспользоваться, если используете действительно спокойный API. Я бы начал с аутентификации.

8 голосов
/ 03 марта 2014

В отношении использования расширения для определения типа данных. Я заметил, что MailChimp API делает это, но я не думаю, что это хорошая идея.

GET /zzz/cars.json/1

GET /zzz/cars.xml/1

Мой звук звучит как хорошая идея, но я думаю, что «старый» подход лучше - использование заголовков HTTP

GET /xxx/cars/1
Accept: application/json

Также HTTP-заголовки намного лучше для связи между типами данных (если кому-то это понадобится)

POST /zzz/cars
Content-Type: application/xml     <--- indicates we sent XML to server
Accept: application/json          <--- indicates we want get data back in JSON format  
4 голосов
/ 20 сентября 2014

Я что-то упустил?

Да. ; -)

Это явление существует из-за единого ограничения интерфейса . REST любит использовать уже существующие стандарты, а не изобретать велосипед. Стандарт HTTP уже доказал свою высокую масштабируемость (сеть работает некоторое время). Почему мы должны починить то, что не сломано?

примечание: единообразное ограничение интерфейса важно, если вы хотите отделить клиентов от сервиса. Это похоже на определение интерфейсов для классов, чтобы отделить их друг от друга. Ofc. здесь единый интерфейс состоит из таких стандартов, как HTTP , MIME-типы , URI , RDF , связанных областей данных , Hydra Vocab и т. Д ...

1 голос
/ 04 января 2018

Билл Веннерс: В своем блоге, озаглавленном «Почему REST Failed», вы сказали, что нам нужны все четыре глагола HTTP - GET, POST, PUT и DELETE, - и посетовали, что поставщики браузеров только GET иPOST. «Зачем нам нужны все четыре глагола? Почему недостаточно GET и POST?

Эллиот Расти Гарольд: В HTTP существует четыре основных метода: GET, POST, PUT,и DELETE. GET используется большую часть времени. Он используется для всего, что безопасно, не вызывает побочных эффектов. GET может быть добавлен в закладки, кэширован, связан, пропущен через прокси-сервер. Это оченьмощная операция, очень полезная операция.

POST, напротив, пожалуй, самая мощная операция. Она может делать все что угодно. Нет пределов тому, что может произойти, и в результате вы должны быть очень осторожны.с ним. Вы не закладываете его. Вы не кэшируете его. Вы не извлекаете его заранее. Вы ничего не делаете с POST, не спрашивая пользователя. Хотите ли вы сделать это? Если пользовательнажимает кнопку, вы можетеПОСТ ПОЛУЧИТЬ некоторый контент.Но вы не собираетесь смотреть на все кнопки на странице и начать случайное нажатие на них.В противоположность этому браузеры могут просматривать все ссылки на странице и предварительно извлекать их, или предварительно извлекать те, которые, по их мнению, наиболее вероятно последуют далее.И действительно, некоторые браузеры, расширения Firefox и другие инструменты пытались сделать это в тот или иной момент.

PUT и DELETE находятся в середине между GET и POST.Разница между PUT или DELETE и POST заключается в том, что PUT и DELETE * идемпотентны, тогда как POST нет.PUT и DELETE могут быть повторены при необходимости.Допустим, вы пытаетесь загрузить новую страницу на сайт.Скажем, вы хотите создать новую страницу на http://www.example.com/foo.html,, поэтому вы вводите свой контент и помещаете его по этому URL.Сервер создает эту страницу по указанному вами URL.Теперь давайте предположим, что по какой-то причине ваше сетевое соединение обрывается.Вы не уверены, запрос прошел или нет?Возможно, сеть работает медленно.Возможно, возникла проблема с прокси-сервером.Поэтому вполне нормально попробовать это снова или снова - столько раз, сколько захотите.Потому что ПОДКЛЮЧЕНИЕ одного и того же документа к одному и тому же URL десять раз не будет отличаться от размещения его один раз.То же самое верно для удаления.Вы можете УДАЛИТЬ что-нибудь десять раз, и это то же самое, что удалить это один раз.

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

Пожалуйста, посетите URL для более подробной информации. http://www.artima.com/lejava/articles/why_put_and_delete.html

Обновление:

Идемпотентные методы Идемпотентный HTTP-метод - это HTTP-метод, который можно вызывать много раз без разных результатов.Не имеет значения, если метод вызывается только один раз или десять раз.Результат должен быть таким же.Опять же, это относится только к результату, а не к самому ресурсу.Этим все еще можно манипулировать (например, отметкой времени обновления, при условии, что эта информация не используется совместно в (текущем) представлении ресурса.

Рассмотрим следующие примеры:

a = 4;

a ++;

Первый пример идемпотентен: независимо от того, сколько раз мы выполняем этот оператор, a всегда будет 4. Второй пример не идемпотентен. Выполнение этого 10 разприведет к другому результату, как при выполнении 5 раз. Поскольку оба примера меняют значение a, оба являются небезопасными методами.

1 голос
/ 21 июля 2017

Хорошая семантика важна в программировании.

Использование дополнительных методов, помимо GET / POST, будет полезно, потому что это повысит читабельность вашего кода и облегчит его обслуживание.

Почему?

Потому что вы знаете, что GET будет получать данные из вашего API. Вы знаете, что POST добавит новые данные в вашу систему. Вы знаете, что PUT сделает обновления. DELETE удалит строки и т. Д.,

Я обычно структурирую свои RESTFUL Web Services так, чтобы у меня был обратный вызов функции, названный так же, как метод.

Я использую PHP, поэтому я использую function_exists (я думаю, что он называется). Если функция не существует, я выбрасываю 405 (МЕТОД НЕ РАЗРЕШЕН).

0 голосов
/ 27 февраля 2019

REST в основном ( wiki ):

  1. Клиент-серверная архитектура
  2. Безгражданство
  3. кэширование
  4. Многоуровневая система
  5. Код по запросу (необязательно)
  6. Единый интерфейс

REST - это не протокол, это принципы. Различные урисы и методы - кто-то, так называемые, лучшие практики.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...