Особенности разработки REST API на OctoberCMS

В данном уроке мы рассмотрим разработку REST API на основе OctoberCMS.

Для чего это может понадобиться? Например, для создания роутов для последующего обращения к ним через AJAX.

Тут читатель может возразить, что в October для этого есть встроенный
AJAX-фреймворк, работающий с компонентами и методами, находящимися прямо в файле страницы и будет прав. Но в некоторых случаях встроенный
AJAX-фреймворк может быть не удобен или совсем не подходить. Особенно, при внедрении сторонних библиотек с динамической подгрузкой данных, таких как Select2.

Также, как показала практика, OctoberCMS отлично подходит как основа для headless решений, предоставляющих REST API для SPA или мобильных приложений, с удобной админкой в комплекте.

Приступая к работе

Как известно, OctoberCMS основан на Laravel. Из этого следует, что разработка REST API на OctoberCMS будет очень похожа на разработку REST API на Laravel.

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

Начало

Для начала необходимо создать плагин. Для этого, как обычно, пойдем в консоль и попросим artisan создать нам пустой плагин.

Или создадим всё вручную (или даже через Builder), кому как больше нравится.

Далее, для объявления роутов нашего REST API создадим файл /plugins/sandbox/restapi/routes.php и объявим в нем наш первый роут.

Теперь, если обратиться к этому роуту, то мы увидим ответ - hello rest api. Для этого мы обычно используем Postman.

Далее - все как и в случае с Laravel. Только папку для контроллеров нам придется создать самостоятельно. Создадим наш контроллер, например, в файле /plugins/sandbox/restapi/http/controllers/HelloController.php, и добавим роут для него:

Теперь обратимся к роуту /api/hello/John%20Doe и увидим, что наш API отвечает соответствующим образом.

Главное здесь - наследовать контроллеры от Illuminate\Routing\Controller, то есть от базового контроллера Laravel. А не от Backend\Classes\Controller, так как последний предназначен для создания страниц в админ-панели OctoberCMS и плохо подходит для нашей задачи.

Особенности

OctoberCMS - это, в первую очередь, система предназначенная для разработки сайтов с классическим роутингом и генерацией HTML-страниц на сервере, а не REST API, поэтому некоторые вещи для разработки REST API подготовлены не очень хорошо.

Основные вопросы - обработка исключений и CORS.

Обработка исключений

В Laravel, если мы запросим роут страницы через браузер и в процессе обработки запроса будет выброшено исключение - мы увидим красивую страницу с кучей полезной информации. В случае же с XHR запросом - получим json с текстом ошибки, кодом и стеком вызовов. И происходит это автоматически, то есть стандартный обработчик ошибок в Laravel сам понимает, какой ответ нам нужен. В случае с OctoberCMS это не так.

Чтобы в этом убедиться, создадим роут, который, просто выбросит ошибку валидации, а затем обратимся к этому роуту.

Откроем Postman и запросим наш роут, не забывая при этом добавить заголовок X-Requested-With со значением XMLHttpRequest, чтобы приложение понимало, что у нас тут AJAX-запрос и отправлять отрендеренную страницу не нужно.

Не густо! Что ж, значит нам придется сделать обработку исключений самим.

Согласно документации, для этого надо в методе boot класса Plugin нашего плагина добавить конструкцию вида:

Теперь попробуем обратиться к роуту еще раз.

Уже лучше. Но теперь появилась другая проблема: так как мы переопределили обработку для ошибок валидации, то у нас теперь не будет работать стандартная валидация в админке и на фронте.

Для проверки этого утверждения, создадим пустой контроллер для админки, добавим в него метод index и бросим ошибку валидации.

Теперь откроем эту страницу в браузере.

Да - это не то, что мы привыкли видеть в браузере, в случае ошибки.

Для решения этой проблемы мы перенесем регистрацию хэндлера ошибок валидации в новый middleware.

Создадим класс ExceptionsMiddleware, разместим его в /plugins/sandbox/restapi/http/middleware/ExceptionsMiddleware.php и добавим следующий код:

Добавим наш новый middleware в файл routes.php

Если же мы откроем страницу теперь, то увидим, привычную нам картину - роут с ошибкой будет отдавать все, что нам нужно.

CORS

Следующий интересный вопрос - CORS.

Если Вы не знаете, что такое CORS, то CORS (Cross-Origin Resource Sharing) - это механизм, позволяющий с помощью дополнительных заголовков запросов и ответов получать доступ к ресурсам других доменов. Подробнее можно почитать здесь.

В Laravel, начиная с 7-ой версии, есть встроенный middleware для работы с CORS. В OctoberCMS же его нет. А это значит, что этот вопрос нам придется решить самим.

В Laravel встроенный middleware работает на основе пакета fruitcake/laravel-cors. Не будем изобретать велосипед и поступим так же.

Про особенности работы с composer в OctoberCMS рекомендую ознакомиться с документацией. В нашем случае, будем считать, что разрабатываемый плагин предназначен исключительно для текущего проекта, а значит все зависимости будем добавлять в корневой composer.json.

Идем в консоль и просим composer установить нам этот пакет.

Данный пакет требует конфига. Следуя рекомендациям из документации OctoberCMS создем конфиг не в общей папке проекта, а в папке плагина /plugins/sandbox/restapi/config/cors.php

Для чего нужен каждый параметр можно посмотреть здесь.

А затем регистрируем конфиг в методе boot класса Plugin нашего плагина, а также зарегистрируем ServiceProvider пакета и добавим глобальный middleware.

Заключение

Вещи описанные в статье, на самом деле, не обязательные, и разрабатывать REST API на OctoberCMS можно и без них, однако обработка исключений не плохо упрощает жизнь, а CORS - необходимая вещь, если вы разрабатываете API обращение к которому будет происходить с домена отличного от того, на котором это API находится.

Код из статьи можно найти в репозитории