RESTful API - быстрый старт.

Статья — продолжение цикла, рассматривающего создание REST API для MODX со всех сторон.
Часть первая — введение

Рассмотрим как работает встроенный в 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 и соотвественно за группу запросов.

К примеру
Хотите работать с ресурсами?
  • Получить список ресурсов
  • Получить информацию по конкретному ресурсу
  • Добавить новый ресурс
  • Изменить существующий ресурс
  • Удалить ресурс
Создаем условный контроллер Resources.php, который будет отлавливать все запросы направленные по адресу /rest/resources/

Хотите работать с юзерами
Создаем условный контроллер Users.php который будет отлавливать все запросы направленные по адресу /rest/users/

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

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

Что должно быть внутри каждого контроллера

Классы modRestController достаточно автономны и не требуют особой настройки. Работают сразу, практикески из коробки. Достаточно указать лишь класс, с которым мы будем работать и по какому полю сортировать выдачу.
На этом все.

Вот так выглядят два моих класса для работы:
с ресурсами


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


Все — этого достаточно. Остальная работа происходит под капотом в родительском классе.

Естественно это довольно примитивные абстрактные примеры. В продолжении мы сделаем реальное API для действующего интернет-магазина, рассмотрим на практике подводные камни и нюансы, поговорим об инструментарии.
Николай Савин
29 сентября 2019, 08:01
modx.pro
7
365
+22
Поблагодарить автора Отправить деньги

Комментарии: 10

Сергей
29 сентября 2019, 10:13
+1
Было бы интересно, если бы кто — нибудь рассказал, как во встроенном API обстоят дела с token-авторизацией
    Николай Савин
    29 сентября 2019, 10:27
    +1
    Про авторизацию и права еще поговорим
      Сергей Шлоков
      29 сентября 2019, 18:07
      0
      Никак ни с токен-авторизацией, ни с какой другой. Есть всего один абстрактный контроллер, который нужно наследовать. Поэтому разработчику придётся всё писать самостоятельно.
        Сергей
        29 сентября 2019, 18:56
        0
        ну вот я поэтому и пишу) много статей про разные встроенные REST-подобные фичи в последнее время, но до сути необходимых для полноценной работы нормального REST — подобного интерфейса никто не доходит в этих статьях.
          Сергей Шлоков
          29 сентября 2019, 19:56
          +1
          Возможно автор топика дальше раскроет тонкости проверки прав, но в этом топике не сделал акцент, что вот за этим
          // Проверяем, что пользователю предоставлены необходимые права доступа;
          // Бьем по рукам и Возвращаем пользователю ошибку 401 ежели чего
          if (!$rest->checkPermissions()) {
              $rest->sendUnauthorized(true);
          }
          ничего не стоит, хотя комментарий вселяет уверенность, что проверка есть. А если заглянуть в код этого метода, то увидим следующее
          public function checkPermissions() {
              return true;
          }
          Новички могут попасть.
            Николай Савин
            29 сентября 2019, 19:58
            0
            В данном случае я процитировал документацию. Вот прямо скопипастил код. Задача быстрого старта — показать самые самые основы. Практические жизненные примеры попробую описать дальше.
              Сергей
              29 сентября 2019, 20:02
              0
              Это так себе на самом деле REST — API, полноценным REST API modx его назвать сложновато
                iWatchYouFromAfar
                29 сентября 2019, 20:02
                0
                Наверное по этой причине Сергей и пишет rest api… :)
                  Сергей Шлоков
                  29 сентября 2019, 22:31
                  +3
                  REST — это архитектурный стиль. А RESTful API — это реализация этого стиля.
                  Правильно говорить именно RESTful API, но в народе уже прижилось неправильное название REST API.
                  Николай Савин
                  29 сентября 2019, 20:05
                  0
                  Опять же — я цитирую официальный источник. В документации написано RestFul APi. Понятное дело это не полноценное REST. Здесь всего то несколько глаголов поддерживаются из всего зоопарка — и то, насколько я понимаю происходит эмуляция, а не полноценная поддержка.
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        10