RESTful API - быстрый старт.
Статья — продолжение цикла, рассматривающего создание REST API для MODX со всех сторон.
Часть первая — введение
Рассмотрим как работает встроенный в MODX модуль для RESTful API, настроим первое подключение, разберем базовые моменты.
Первый запуск встроенного в MODX еще со времен версии 2.3. REST модуля — происходит довольно быстро и просто. Буквально в три шага.
Шаг 1
В корне проекта создаем новый каталог с произвольным именем. Лучше конечно использовать осмысленное имя. К примеру rest/
В каталог добавляем один единственный файл index.php. В нем подключаем сам MODX и несколько строчек для конфигурирования и вызова нашего модуля
Конфигурируем сервер. То есть объясняем что при обращении по адресу /rest/**/** нужно всего навсего вырезать все что стоит после /rest/ и передать в качестве параметра в файл index.php
Apache:
NGINX:
Для этого обращаемся по адресу /rest/любая_произвольная_строка
Если мы все сделали правильно — то модуль REST подхватит нашу произвольную строку в запросе, попытается найти у себя соответствующий контроллер, которого конечно нет и выдаст специфическую ошибку.

Модуль REST по умолчанию отдает все ответы в сыром JSON формате. Вы знали что Firefox умеет сразу красиво форматировать JSON и показывать его в удобном, отлично читаемом виде? Рекомендую для тестов использовать его.
Сравните как воспроизводят одну и ту же JSON строку Chrome (просто фу!)

и Firefox

Шаг 3
Получаем реальные данные из MODX.
На этом шаге нам понадобится создать дополнительный каталог с контроллерами.
Контроллеры — это классы, каждый из которых отвечает за отдельную таблицу MODX и соотвественно за группу запросов.
К примеру
Хотите работать с ресурсами?
Хотите работать с юзерами
Создаем условный контроллер Users.php который будет отлавливать все запросы направленные по адресу /rest/users/
В общем принцип такой — отдельная таблица (сущность) — отдельный контроллер. Хотя никто конечно не мешает подключать в классе и другие таблицы или даже целые компоненты, оперируя данными из них.
Что нужно знать про контроллеры
Класс modRestService, который определяет какой контроллер вызвать — предполагает несколько правил.
Что должно быть внутри каждого контроллера
Классы modRestController достаточно автономны и не требуют особой настройки. Работают сразу, практикески из коробки. Достаточно указать лишь класс, с которым мы будем работать и по какому полю сортировать выдачу.
На этом все.
Вот так выглядят два моих класса для работы:
с ресурсами

с пользователями

Все — этого достаточно. Остальная работа происходит под капотом в родительском классе.
Естественно это довольно примитивные абстрактные примеры. В продолжении мы сделаем реальное API для действующего интернет-магазина, рассмотрим на практике подводные камни и нюансы, поговорим об инструментарии.
Часть первая — введение
Рассмотрим как работает встроенный в MODX модуль для RESTful API, настроим первое подключение, разберем базовые моменты.
Первый запуск встроенного в MODX еще со времен версии 2.3. REST модуля — происходит довольно быстро и просто. Буквально в три шага.
Шаг 1
В корне проекта создаем новый каталог с произвольным именем. Лучше конечно использовать осмысленное имя. К примеру rest/
В каталог добавляем один единственный файл index.php. В нем подключаем сам MODX и несколько строчек для конфигурирования и вызова нашего модуля
// Подключаем MODX
require_once dirname(dirname(__FILE__)) . '/config.core.php';
require_once MODX_CORE_PATH . 'model/modx/modx.class.php';
$modx = new modX();
$modx->initialize('web');
$modx->getService('error', 'error.modError', '', '');
// Подготовим некоторую базовую конфигурацию и загрузим класс modRestService
$rest = $modx->getService('rest', 'rest.modRestService', '', array(
'basePath' => dirname(__FILE__) . '/Controllers/',
'controllerClassSeparator' => '',
'controllerClassPrefix' => 'MyController',
'xmlRootNode' => 'response',
));
// обрабатывем запрос и возвроащаем ответ
/** @var modRestService $rest */
$rest->prepare();
// Проверяем, что пользователю предоставлены необходимые права доступа;
// Бьем по рукам и Возвращаем пользователю ошибку 401 ежели чего
if (!$rest->checkPermissions()) {
$rest->sendUnauthorized(true);
}
$rest->process();Шаг 2Конфигурируем сервер. То есть объясняем что при обращении по адресу /rest/**/** нужно всего навсего вырезать все что стоит после /rest/ и передать в качестве параметра в файл index.php
Apache:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule ^(.*)$ rest/index.php?_rest=$1 [QSA,NC,L]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*)$ rest/index.php [QSA,NC,L]NGINX:
location /rest/ {
try_files $uri @modx_rest;
}
location @modx_rest {
rewrite ^/rest/(.*)$ /rest/index.php?_rest=$1&$args last;
}После этого уже можно проверить работу модуля. Для этого обращаемся по адресу /rest/любая_произвольная_строка
Если мы все сделали правильно — то модуль REST подхватит нашу произвольную строку в запросе, попытается найти у себя соответствующий контроллер, которого конечно нет и выдаст специфическую ошибку.

Модуль REST по умолчанию отдает все ответы в сыром JSON формате. Вы знали что Firefox умеет сразу красиво форматировать JSON и показывать его в удобном, отлично читаемом виде? Рекомендую для тестов использовать его.
Сравните как воспроизводят одну и ту же JSON строку Chrome (просто фу!)

и Firefox

Шаг 3
Получаем реальные данные из MODX.
На этом шаге нам понадобится создать дополнительный каталог с контроллерами.
Контроллеры — это классы, каждый из которых отвечает за отдельную таблицу MODX и соотвественно за группу запросов.
К примеру
Хотите работать с ресурсами?
- Получить список ресурсов
- Получить информацию по конкретному ресурсу
- Добавить новый ресурс
- Изменить существующий ресурс
- Удалить ресурс
Хотите работать с юзерами
Создаем условный контроллер Users.php который будет отлавливать все запросы направленные по адресу /rest/users/
В общем принцип такой — отдельная таблица (сущность) — отдельный контроллер. Хотя никто конечно не мешает подключать в классе и другие таблицы или даже целые компоненты, оперируя данными из них.
Что нужно знать про контроллеры
Класс modRestService, который определяет какой контроллер вызвать — предполагает несколько правил.
- Все контроллеры располагаются в определенном, заранее указанном в классе каталоге. Предсказуемо — именуем каталог Controllers
- Имя каждого контроллера равно запросу. Как я писал выше — для ресурсов это будет запрос /rest/resources/
и файл Resources.php, для пользователей /rest/users/ и файл Users.php. - Каждый контроллер это класс, расширяющий родительский класс modRestController. Мы также обязаны задать определенное имя класса. Оно формируется из двух обязательных частей. Префикс, общий для всех контроллеров + именование контроллера. Префикс задается в первоначальном вызове класса modRestController в index.php.
Указав общий префикс MyController, мы получим следующие классы
— class MyControllerResources extends modRestController
— class MyControllerUsers extends modRestController
// Подготовим некоторую базовую конфигурацию и загрузим класс modRestService
$rest = $modx->getService('rest', 'rest.modRestService', '', array(
//Указываем имя каталога с контроллерами
'basePath' => dirname(__FILE__) . '/Controllers/',
'controllerClassSeparator' => '',
//Указываем префис для именования классов контроллеров
'controllerClassPrefix' => 'MyController',
'xmlRootNode' => 'response',
));Что должно быть внутри каждого контроллера
Классы modRestController достаточно автономны и не требуют особой настройки. Работают сразу, практикески из коробки. Достаточно указать лишь класс, с которым мы будем работать и по какому полю сортировать выдачу.
На этом все.
Вот так выглядят два моих класса для работы:
с ресурсами

с пользователями

Все — этого достаточно. Остальная работа происходит под капотом в родительском классе.
Естественно это довольно примитивные абстрактные примеры. В продолжении мы сделаем реальное API для действующего интернет-магазина, рассмотрим на практике подводные камни и нюансы, поговорим об инструментарии.
Комментарии: 28
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Подскажите как одолеть вопрос? Может есть заметки на эту тему.
Дело в том что авторизация в MODX хранится в сессии, что делает достаточно сложным вопрос опознавания юзера, который обращается к сайту по API. Это нужно идентификатор сессии получать и подписывать каждый запрос, да еще и поднимать уже существующую сессию по присланному идентификатору. Я пока не осилил.
Есть несколько путей попроще. Например jwt сессии когда все хранится на стороне клиента.
Я вот по пути Laravel обычно иду. Делаю идентификатор пользователя, подписываю им запросы и при каждом запросе авторизую пользователя. Но тут тоже есть подводные камни. Авторизацию и права нужные вы получите а вот с другими компонентами использующими сессию в работе все также проблематично пользоваться. Тем же minishop2 с его сессионной корзиной.
Авторизация происходит через обращение на вашсайт/rest/auth. В GET-запросе должны находиться username и password. Далее можно обращаться к вашсайт/rest/myPackage или посмотреть как в файле реализована обёртка с проверкой.
Для меня пока хватит и этого. В будущем попробую прикрутить токен, благо реализаций полно для MODX.
А что делать с аутентификацией при каждом последующем запросе?
Б — безопасность)
Учитывая отсутствие каких-либо внятных альтернатив — пойдет и такое. Мне был важен сам метод проверки с простейшим примером.
ничего не стоит, хотя комментарий вселяет уверенность, что проверка есть. А если заглянуть в код этого метода, то увидим следующее
Новички могут попасть.
Правильно говорить именно RESTful API, но в народе уже прижилось неправильное название REST API.
Ровно там же, где находится управление ЧПУ.
upd
я криворукий просто, в htaccess намудрил