Skip to content

Контроллеры

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\GetController

2. 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\SectionsController

3. Action по умолчанию, название контроллера по умолчанию

Шаблон

\Realweb\Api\Module\Module\Controller\Controller-Path\IndexController

Пример

Ендпоинт: /api/faq/item-sections/

\Realweb\Api\Module\Faq\Controller\Item\Sections\IndexController

Валидация данных

Перед вызовом метода Action будет вызван метод checkActionParams в котором и следует проводить валидацию данных. При наличии ошибок необходимо в компонент вызова добавить ошибку валидации. В этом случае основной метод get не выполнится.

Пример
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\EntityController
php
//Для сущности
Catalog\Model\Element\Property\Field\Entity
//Контроллеры будут такие
Catalog\Controller\Element\Property\Field\CollectionController
Catalog\Controller\Element\Property\Field\EntityController

Frontend

В том случае, если разработчика не устраивает название метода из спецификации, то можно применить прием алиасов, например

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();
	}
}