Appearance
Контроллеры
HTTP запрос
Точкой входа по умолчанию для всех контроллеров является страница с адресом /api/.
Для изменения точки входа необходимо воспользоваться методом
php
\Realweb\Api\Controller::setApiFolder('/some-another-end-point/');в прологе страницы (init.php)
Контроллеры подключаются компонентом realweb.api.
Контроллеры поддерживают 5 типов запросов и должны содержать следующие публичные методы
GET-public function get()получение данныхPOST-public function post()создание данныхDELETE-public function delete()удаление данныхPUT-public function put()изменение данных целикомPATCH-public function patch()изменение части данных
Каждый из методов должен вернуть данные, которые будут обработаны функцией json_encode и отданы в браузер. В общем случае это массив.
Точка входа
В точке входа для обращения к методам api располагается компонент realweb.api. В файле urlrewrite.php необходимо разместить правило
php
$arUrlRewrite = array(
array(
'CONDITION' => '#^/api/#',
'RULE' => '',
'ID' => null,
'PATH' => '/api/index.php',
'SORT' => 100,
),
);Без HTTP запроса
Помимо прямого обращения к методам контроллеров через HTTP, их также можно использовать для внутренних нужд - для получения закешированных коллекций сущностей или самих сущностей. В таком случае нет необходимости отдавать данные в виде массива, лучше сразу отдавать экземпляр объекта.
Пример реализации
php
namespace Realweb\Api\Module\Catalog\Controller;
use Realweb\Api\Module\Catalog;
/**
* Class \Realweb\Api\Module\Advantages\Controller\ElementController
*/
class ElementController extends \Realweb\Api\Controller
{
protected ?Catalog\Model\Element\Collection $_collection = null;
public function get(): array
{
$obNav = $this->getNav();
$arResult = \Realweb\Api\Model\Main\Cache::getInstance()
->setId($obNav)
->setDir(__CLASS__)
->addTag(Catalog\Model\Element\Database->getCacheTag())
->get(fn () => $this->_getList($obNav))
;
/** @var Catalog\Model\Element\Collection $obCollection */
$obCollection = $arResult['collection'];
$this->_setCollection($obCollection);
if ($this->isReturnJsonData()) {
return $obCollection->toJson();
}
return array();
}
public function getCollection(): Catalog\Model\Element\Collection
{
if ($this->_collection === null) {
$this->setReturnJsonData(false);
$this->get();
}
return $this->_collection;
}
protected function _setCollection(Catalog\Model\Element\Collection $obCollection): self
{
$this->_collection = $obCollection;
return $this;
}
protected function _getList(\Realweb\Api\Model\Main\Pagination $obNav): array
{
$obCollection = Catalog\Model\Element\Database::getObjectCollection($obNav);
return array(
'collection' => $obCollection,
'pagination' => $this->getPaginatorInfo($obNav),
);
}
}Именование контроллеров
Название контролера и реализованные в нем методы определяют приоритет вызова. Контроллеры должны иметь постфикс Controller и расширять класс \Realweb\Api\Controller
Все url запросов к api имеют вид /api/MODULE/CONTROLLER/ID/
При этом сам контроллер может содержать составные части с разделителем -, например GET запрос /api/iblock/property-enum/ вызовет контроллер EnumController
Контроллер по умолчанию - IndexController
Действие по умолчанию - GET
Получение переменной ID из урл возможна методом контроллера
php
$iId = $this->getRouteId();Приоритет определения текущего контроллера
Module - модуль запроса
Controller-Path - контроллер запроса. Разделитель "-" заменяется на пространство имен (Controller\Path)
Action - метод запроса - Get, Post, Delete, Put, Patch
1. Action явно задан в названии контроллера
Шаблон
\Realweb\Api\Module\Module\Controller\Controller-Path\ActionControllerПример
Ендпоинт: /api/faq/item-sections/
Контроллер:
\Realweb\Api\Module\Faq\Controller\Item\Sections\GetController2. Action по умолчанию
Action в зависимости от HTTP запроса (соответственно класс должен иметь методы get, post, delete, put или patch)
Шаблон
\Realweb\Api\Module\Module\Controller\Controller-PathControllerПример
Ендпоинт: /api/faq/item-sections/
\Realweb\Api\Module\Faq\Controller\Item\SectionsController3. Action по умолчанию, название контроллера по умолчанию
Шаблон
\Realweb\Api\Module\Module\Controller\Controller-Path\IndexControllerПример
Ендпоинт: /api/faq/item-sections/
\Realweb\Api\Module\Faq\Controller\Item\Sections\IndexControllerВалидация данных
Перед вызовом метода Action будет вызван метод check в котором и следует проводить валидацию данных. При наличии ошибок необходимо в компонент вызова добавить ошибку валидации. В этом случае основной метод ActionParamsget не выполнится.
Пример
php
class IndexController extends \Realweb\Api\Controller
{
private ?Element\Entity $_entity = null;
public function checkGetParams(): void
{
if (!$this->getRequestParam('path')) {
$this->getComponent()->addErrorNoParams();
}
}
public function get(): ?array
{
//При наличии ошибок этот метод не выполнится
...
}
}Параметры
Установка параметров контроллера
Параметры из HTTP запроса устанавливаются автоматически. Также доступны следующие методы для установки параметров
setRequestParams- установка параметров HTTP запроса, устанавливается автоматически в компоненте realweb.api, не рекомендуется переопределятьsetParams- параметры, устанавливаемые программистом
php
use Realweb\Api\Module\Catalog;
$obCollection = (new Catalog\Controller\Element\CollectionController())
->setRequestParams(array()) //Переопределение параметров из HTTP запроса
->setRequestParam('param','value') // Установка HTTP параметра
->setParams(array()) //Установка параметров контроллера
->setParam('param','value') // Установка значения параметра
->getCollection()
;Получение параметров в контроллере
Для получения параметров с привидением типа переменной существуют встроенные методы, принимающие 2 параметра: название параметра и значение по умолчанию
php
$arParam = $this->getParamArray('param',array()); //Массив
$bParam = $this->getParamBool('param',false); // Булево
$strParam = $this->getParamString('param','');// Строка
$iParam = $this->getParamNumber('param',0);// Число
$mParam = $this->getParam('param', null); // Без привидения типа
$arAllParams = $this->getParams(); // Все параметрыТакже можно получать параметры непосредственно из запроса
php
$arParams = $this->getRequestParams();
$strParam = $this->getRequestParam('param','default');Объект пагинации
Контроллеры обладают встроенным методом получения пагинации для передачи параметров пагинации и параметров в запрос БД
php
/** @var \\Realweb\Api\Model\Main\Pagination $obPagination */
$obPagination = $this->getPagination();Класс \Realweb\Api\Model\Main\Pagination предоставляет возможность управлять как пагинацией сущностей, так и установкой параметров запроса. В основные запросы БД передается экземпляр класса.
public static function getObjectCollection(?Pagination $obNav = null): Collection- получение коллекции сущностей, параметры запроса передаются в объекте пагинацииpublic static function getObject(?Pagination $obNav = null): Entity- получение сущности, параметры запроса передаются в объекте пагинации
Пагинация
Для установки пагинации существует методы:
$obPagination->setPageSize($iSize)Размер страницы$obPagination->setCurrentPage($iPage)Текущая страница$obPagination->setAllRecords();Все записи
Модель базы данных построит запрос ограничения выборки автоматически
Параметры
Установка параметров
php
$obPagination->setParam('param','value');Получение параметров
Для получения параметров с привидением типа данных существуют встроенные методы, принимающие 2 параметра: название параметра и значение по умолчанию
php
$arParam = $obPagination->getParamArray('param',array()); //Массив
$bParam = $obPagination->getParamBool('param',false); // Булево
$strParam = $obPagination->getParamString('param','');// Строка
$iParam = $obPagination->getParamNumber('param',0);// Число
$mParam = $obPagination->getParam('param', null); // Без привидения типа
$arAllParams = $obPagination->getParams(); // Все параметрыРекомендации
В модуле realweb.api.module используется 2 типа контроллеров, которые условно можно назвать
- Frontend - используется для вывода json на фронтенд
- Backend - используется для внутренних нужд бекенда.
Рекомендация
Для сложных модулей (catalog, order) можно сразу разделить контроллеры 2х типов по разным директориям Frontend и Backend.
Backend
В основном, на проекте используются контроллеры для получения сущностей БД.
Для получения списка элементов контроллер следует называть CollectionController, для получения самой сущности - EntityController и располагать в директории, “схожей” с директорией сущности. Например
php
//Для сущности
Catalog\Model\Element\Entity
//Контроллеры будут такие
Catalog\Controller\Element\CollectionController
Catalog\Controller\Element\EntityControllerphp
//Для сущности
Catalog\Model\Element\Property\Field\Entity
//Контроллеры будут такие
Catalog\Controller\Element\Property\Field\CollectionController
Catalog\Controller\Element\Property\Field\EntityControllerFrontend
В том случае, если разработчика не устраивает название метода из спецификации, то можно применить прием алиасов, например
php
Alias\Model\Classes::init();
class Classes
{
public static function init(): void
{
// Меню
class_alias('\Realweb\Api\Module\Menu\Controller\HeaderController', '\Realweb\Api\Module\Nav\Controller\HeaderController');
class_alias('\Realweb\Api\Module\Menu\Controller\FooterController', '\Realweb\Api\Module\Nav\Controller\FooterController');
}
}Встроенные контроллеры
Контроллер получения коллекции
Контроллер \Realweb\Api\Controller\CollectionController представляет собой "заготовку" для получения коллекции любой сущности БД.
Обязательным методом наследуемого класса является _getDataBase - возвращение модели базы данных.
Встроенные методы:
_initParams- изменение данных пагинации: установка параметров фильтрации, количества элементов на странице и т.д._getCacheTime- установка время кеширования, 0 - не кешировать_getCacheTag- установка тегов для кеша, возвращает массив, строку илиnullесли тегов нет_process- выполнение дополнительных манипуляций с коллекцией до сохранения в кеш
Пример
php
class CollectionController extends \Realweb\Api\Controller\CollectionController
{
/**
* @return Offer\Collection
*/
public function getCollection(): \Realweb\Api\Model\Data\Collection
{
return parent::getCollection();
}
protected function _getDataBase(): string
{
return Offer\Database::class;
}
protected function _initParams(): void
{
parent::_initParams();
$this->getPagination()
->setParam('ids', $this->getParamArray('ids'));
}
/**
* @param Offer\Collection $obCollection
*/
protected function _process(\Realweb\Api\Model\Data\Collection $obCollection): void
{
$obCollection->processData();
}
protected function _getCacheTime(): int
{
return 3600;
}
protected function _getCacheTag(): array
{
return array(
Offer\Database::getCacheTag(),
Element\Database::getCacheTag(),
);
}
}Туториал по реализации своего контроллера
Контроллер получения сущности
Контроллер \Realweb\Api\Controller\EntityController представляет собой "заготовку" для получения любой сущности БД.
Обязательным методом наследуемого класса является _getDataBase - возвращение модели базы данных.
_initParams- изменение данных пагинации: установка параметров фильтрации, количества элементов на странице и т.д._getCacheTime- установка время кеширования, 0 - не кешировать_getCacheTag- установка тегов для кеша, возвращает массив, строку илиnullесли тегов нет_processCollection- выполнение дополнительных манипуляций с коллекцией (в которой находится единственная найденная сущность) до сохранения в кеш_processEntity- выполнение дополнительных манипуляций с полученной сущностью до сохранения в кеш
Пример
php
class EntityController extends \Realweb\Api\Controller\EntityController
{
/**
* @return Offer\Entity|null
*/
public function getEntity(): ?\Realweb\Api\Model\Data\Entity
{
return parent::getEntity();
}
protected function _getDatabase(): string
{
return Offer\Database::class;
}
protected function _getCacheTag(): string
{
return Catalog\Model\Element\Database::getCacheTag();
}
protected function _initParams(): void
{
parent::_initParams();
$this->getPagination()
->setParam('id', $this->getParamNumber('id'))
->setParam('code', $this->getParamString('code'));
}
/**
* @param Offer\Collection $obCollection
*/
protected function _processCollection(\Realweb\Api\Model\Data\Collection $obCollection): void
{
$obCollection->processData();
}
/**
* @param Offer\Entity $obEntity
*/
protected function _processEntity(\Realweb\Api\Model\Data\Entity $obEntity): void
{
$obEntity->processMetaValues();
}
}