Pull to refresh

RESTful PHP — 5 простых советов

Reading time 4 min
Views 83K
REST (Representational state transfer) — это архитектурный стиль или свод соглашений для web-приложений и сервисов, основанный на манипулировании ресурсами и спецификацией HTTP. Впервые об этом заговорил Рой Филдинг (Roy Fielding) — один из отцов основателей HTTP (Hypertext Transfer Protocol).

Web-приложения зачастую игнорируют спецификацию HTTP и двигаются вперёд используя полюбившиеся возможности: GET и POST, 200 OK и 404 NOT FOUND. Так как используются программируемые web-приложения, со своими собственными API, то решение игнорировать спецификацию HTTP, может создать проблемы в дальнейшем. Как следствие — имеем множество приложений с интерфейсами GET и POST. Например интерфейс удаления пользователя: GET /user/1/delete против POST /user/delete {id=1}; в случае REST можно указать /user/1 это ресурс, а удаление HTTP метод DELETE.

Такие важные методы HTTP, как — POST, GET, PUT и DELETE — зачастую сравнивают с CREATE, READ, UPDATE, DELETE (CRUD) операциями маниулирования базами данных. HTTP отделяет понятие web-сервер и web-браузер. Это позволяет каждой реализации отличаться от других подобных, основанных на «клиент/сервер» принципе.

Теперь самое время взглянуть на примеры, так будет понятнее.

1. Использование методов PUT и DELETE


В PHP можно без проблем определить используемый HTTP метод, достаточно обратиться к переменной системного массива $_SERVER['REQUEST_METHOD']; В случае web-браузеров там прописан либо GET, либо POST метод. Для клиентских приложений REST требуется поддержка PUT, DELETE и желательно OPTIONS и прочих. Но к сожалению в PHP нет $_PUT и $_DELETE, в отличии от $_GET и $_POST. Вот способ исправить упущение:

$_PUT = array(); 
if($_SERVER['REQUEST_METHOD'] == 'PUT') { 
  $putdata = file_get_contents('php://input'); 
  $exploded = explode('&', $putdata);  
 
  foreach($exploded as $pair) { 
    $item = explode('=', $pair); 
    if(count($item) == 2) { 
      $_PUT[urldecode($item[0])] = urldecode($item[1]); 
    } 
  } 
}


Таким образом у нас появляется массив $_PUT, похожий на $_POST за исключением суперглобальности.

2. Отправка выборочных HTTP 1.1 заголовков


PHP позволяет кастомизировать заголовки посылаемые клиенту. В свою очередь заголовок содержит код ответа от сервера. По умолчанию PHP ответит кодом 200 OK на успешный запрос, на использование функции die() или на создание нового ресурса. Собственно есть два пути кастомизировать ситуацию:

header('HTTP/1.1 404 Not Found'); 
// или 
header('Location: http://www.foo.com/bar', true, 201); // 201 CREATED


Первый вариант достаточно стандартный метод установки кода ответа. Если же потребуется указать перенаправление на ресурс «201 Created» или «301 Moved Permanently», это несложно реализовать, указав код в третьем параметре функции header(), как показано в примере. Второй пример можно заменить на более удобочитаемый код:

header('HTTP/1.1 201 Created'); 
header('Location: http://www.foo.com/bar');


3. Отправка значимых HTTP заголовков


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

201 Created — используется если был создан новый ресурс. Должен применяться с функционалом направления на ресурс, например /tech/news, т.к. сам автоматического направления не использует.

202 Accepted — как бы говорит клиенту «ваш заказ принят и скоро будет обработан». В отличие от кода 201, который отсылается после создания ресурса, код 202 ставит запрос в очередь.

204 No Content — В связке с кэшированием и условным GET запросом (запросы с If-Modified-Since/If-None-Match заголовками), позволяет сказать web-приложениям «контент не изменился, продолжайте юзать кэшированную версию», без повторной переработки и отправки кэша.

401 Unauthorized — должен использоваться при попытке обратиться к ресурсу, требующему определённого уровня доступа. Используется в связке с www-authentication.

500 Internal Server Error — гораздо лучше 200 OK, когда PHP скрипт уже не дышит или привёл к исключению.

Естественно заголовков гораздо больше, на эту тему неоднократно было написано, приведённые выше — всего лишь примеры.

4. Не используйте $_SESSION


Настоящее RESTful PHP приложение должно быть полностью независимо, все запросы должны содержать достаточно информации чтобы на них можно было отреагировать без дополнительных усилий со стороны сервера. На практике это подразумевает сохранение авторизационной информации в куках с датой (timestamp) и контрольной суммой. Дополнительная информация так же может быть сохранена в куках. В случае если требуется сохранить большие объёмы данных, их можно уложить в базу данных, авторизационную информацию стоит оставить в куках. UPD: Надо оговориться, что использование cookies не в полной мере соответствует идеологии REST, т.к. сеансовые связи сохраняются. Но в случае cookies информация о сеансе хранится у клиента, а в случае использования session сеансовые связи хранятся во временной директории сервера и в сессионной куке клиента (если включен «session.use_cookies»).

5. Тестирование при помощи cURL или rest-client


cURL позволяет легко выполнять любые HTTP методы для нужного ресурса. Можно передавать любые параметры запросов и заголовков, а так же проверять ответные заголовки и данные. Инструмент коммандной строки «curl», стандартен для большинства *nix систем. Для пользователей Windows подойдёт MinGW/MSYS.

Пример использования и базовые опции:

# curl -X PUT www.foo.com/bar/1 -d "some=var" -d "other=var2" -H "Accept: text/json" -I

-X [METHOD] определяет HTTP метод.
-d «name=value» устанавливает имя и значения переменных в POST/PUT.
-H [HEADER] устанавливает заголовок.
-I отображает заголовки ответа.

Так же существует бесплатный графический, основанный на Java/Swing, rest-client для тестирования REST. Он так же поддерживает JSON/XML.

Полезные ссылки по теме


Оригинал статьи на английском языке
Web-разработка → Архитектура REST
Полезнейшая статья по REST на английском языке
RESTful PHP фреймворк
REST: the quick pitch
Method Definitions

UPD:

Где так или иначе используется


Flickr Services
Yahoo! Maps Web Services
Mambo's RESTful API

* restful (англ.) — успокоительный; успокаивающий.
Tags:
Hubs:
+52
Comments 122
Comments Comments 122

Articles