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
Было бы интересно, если бы кто — нибудь рассказал, как во встроенном API обстоят дела с token-авторизацией
Про авторизацию и права еще поговорим
Интересует данный момент. Могу многое сделать кроме авторизации в MODX REST.
Подскажите как одолеть вопрос? Может есть заметки на эту тему.
Подскажите как одолеть вопрос? Может есть заметки на эту тему.
Я сам не особо этот вопрос одолел.
Дело в том что авторизация в MODX хранится в сессии, что делает достаточно сложным вопрос опознавания юзера, который обращается к сайту по API. Это нужно идентификатор сессии получать и подписывать каждый запрос, да еще и поднимать уже существующую сессию по присланному идентификатору. Я пока не осилил.
Есть несколько путей попроще. Например jwt сессии когда все хранится на стороне клиента.
Я вот по пути Laravel обычно иду. Делаю идентификатор пользователя, подписываю им запросы и при каждом запросе авторизую пользователя. Но тут тоже есть подводные камни. Авторизацию и права нужные вы получите а вот с другими компонентами использующими сессию в работе все также проблематично пользоваться. Тем же minishop2 с его сессионной корзиной.
Дело в том что авторизация в MODX хранится в сессии, что делает достаточно сложным вопрос опознавания юзера, который обращается к сайту по API. Это нужно идентификатор сессии получать и подписывать каждый запрос, да еще и поднимать уже существующую сессию по присланному идентификатору. Я пока не осилил.
Есть несколько путей попроще. Например jwt сессии когда все хранится на стороне клиента.
Я вот по пути Laravel обычно иду. Делаю идентификатор пользователя, подписываю им запросы и при каждом запросе авторизую пользователя. Но тут тоже есть подводные камни. Авторизацию и права нужные вы получите а вот с другими компонентами использующими сессию в работе все также проблематично пользоваться. Тем же minishop2 с его сессионной корзиной.
Не могу не поделиться одним из вариантов.
Авторизация происходит через обращение на вашсайт/rest/auth. В GET-запросе должны находиться username и password. Далее можно обращаться к вашсайт/rest/myPackage или посмотреть как в файле реализована обёртка с проверкой.
Для меня пока хватит и этого. В будущем попробую прикрутить токен, благо реализаций полно для MODX.
Авторизация происходит через обращение на вашсайт/rest/auth. В GET-запросе должны находиться username и password. Далее можно обращаться к вашсайт/rest/myPackage или посмотреть как в файле реализована обёртка с проверкой.
Для меня пока хватит и этого. В будущем попробую прикрутить токен, благо реализаций полно для MODX.
С авторизацией понятно, этот вопрос как раз и не сложный.
А что делать с аутентификацией при каждом последующем запросе?
А что делать с аутентификацией при каждом последующем запросе?
гет параметрами логин и пароль отправлять эт конечно круто)))
Б — безопасность)
Б — безопасность)
Я конечно такой себе программист, особенно с PHP/MODX, но прекрасно понимаю всю глупость отправки подобным способом.
Учитывая отсутствие каких-либо внятных альтернатив — пойдет и такое. Мне был важен сам метод проверки с простейшим примером.
Учитывая отсутствие каких-либо внятных альтернатив — пойдет и такое. Мне был важен сам метод проверки с простейшим примером.
Никак ни с токен-авторизацией, ни с какой другой. Есть всего один абстрактный контроллер, который нужно наследовать. Поэтому разработчику придётся всё писать самостоятельно.
ну вот я поэтому и пишу) много статей про разные встроенные REST-подобные фичи в последнее время, но до сути необходимых для полноценной работы нормального REST — подобного интерфейса никто не доходит в этих статьях.
Возможно автор топика дальше раскроет тонкости проверки прав, но в этом топике не сделал акцент, что вот за этим
// Проверяем, что пользователю предоставлены необходимые права доступа;
// Бьем по рукам и Возвращаем пользователю ошибку 401 ежели чего
if (!$rest->checkPermissions()) {
$rest->sendUnauthorized(true);
}
ничего не стоит, хотя комментарий вселяет уверенность, что проверка есть. А если заглянуть в код этого метода, то увидим следующееpublic function checkPermissions() {
return true;
}
Новички могут попасть.
В данном случае я процитировал документацию. Вот прямо скопипастил код. Задача быстрого старта — показать самые самые основы. Практические жизненные примеры попробую описать дальше.
Это так себе на самом деле REST — API, полноценным REST API modx его назвать сложновато
Наверное по этой причине Сергей и пишет rest api… :)
REST — это архитектурный стиль. А RESTful API — это реализация этого стиля.
Правильно говорить именно RESTful API, но в народе уже прижилось неправильное название REST API.
Правильно говорить именно RESTful API, но в народе уже прижилось неправильное название REST API.
Опять же — я цитирую официальный источник. В документации написано RestFul APi. Понятное дело это не полноценное REST. Здесь всего то несколько глаголов поддерживаются из всего зоопарка — и то, насколько я понимаю происходит эмуляция, а не полноценная поддержка.
Благодарю за статью!
Странный вопрос. Конфигурирование сервера пишется в файле htaccess в корне проекта.
Ровно там же, где находится управление ЧПУ.
Ровно там же, где находится управление ЧПУ.
да)
Мне кажется эта задача сложновата для вас. Может стоит привлечь более опытного разработчика?
Только у меня на всех страницах это сообщение. На главной и прочих
Решено. Надо в /rest создать .htaccess(копия корневого .htaccess) и туда вставить код из шага 2
Сделал все по инструкции, и при обращении например по адресу site.ru/rest/resources/ меня редиректит на 404.
upd
я криворукий просто, в htaccess намудрил
upd
я криворукий просто, в htaccess намудрил
Рекомендую использовать ZoomX для построения API. Текущая статья — устаревшая. Архивная я бы сказал
Да, увидел вашу статью, решил все таки ZoomX потестить. С modRest знатно повозился, чтобы достичь нужного результата
а что именно Вы намудрили? подскажите, у меня такие же проблемы с htaccess, не понимаю почему
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.