REST API-зачем использовать PUT DELETE POST GET?

Итак, я просматривал некоторые статьи по созданию REST API. И некоторые из них предлагают использовать все типы HTTP-запросов: like PUT DELETE POST GET. Мы бы создали, например .в 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:

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

8 ответов


идея REпредставления SТэйт Transfer не о доступе к данным самым простым способом.

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

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

например:

GET: /cars/make/chevrolet

, вероятно, собирается вернуть список автомобилей chevy. хороший REST api может даже включать некоторые параметры вывода в строку запроса, например ?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] }

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

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

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

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

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

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

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 элемент был добавлен между when /oldest был запрошен и когда delete был выдан.


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

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

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

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

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

источник


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


Вы спрашивали:

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

из Википедии на остальное:

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

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

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

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

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

Вы спрашивали:

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

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

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


в отношении использования расширения для определения типа данных. Я заметил, что 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  

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

да. ;-)

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

Примечание: ограничение uniform interface важно, если вы хотите отделите клиентов от службы. Это похоже на определение интерфейсов для классов, чтобы отделить их друг от друга. Конвертер ofc. здесь единый интерфейс состоит из таких стандартов, как адресу http, типы MIME, URI, RDF, связанные данные vocabs, hydra vocab, etc...


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

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

Почему?

потому что вы знаете, что GET будет извлекать данные из вашего api. Вы знаете, что POST добавит новые данные в вашу систему. Сказал, что будет делать обновления. Удалить удалить строки и т. д., и т. д.

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

Я использую PHP, поэтому я использую function_exists (я думаю, что его называют). Если функция не существует, я бросаю 405 (метод не разрешен).


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

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

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

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

напротив, сообщение, может вызвать что-то другое, чтобы произойти каждый раз. Представьте, что вы проверяете из интернет-магазина по нажав кнопку "купить". Если вы отправите этот запрос снова, вы можете в конечном итоге купить все в своей корзине во второй раз. Если вы отправите его снова, вы купили его в третий раз. Вот почему браузеры должны быть очень осторожны с повторением операций 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, оба являются небезопасными методами.