События
Before-обработчик выполняется перед проверкой или действием, After — после соответствующего этапа. Условия вызова зависят от события: например, onAfterIpAccess вызывается только при успешной IP-проверке. After не обязательно означает «после отправки ответа»: для этого предусмотрен только onAfterResponse.
Порядок событий и контракт результата описаны отдельно.
Подключение
В local/php_interface/init.php добавьте общий блок. Нужные обработчики из следующих примеров размещайте внутри if, после создания $eventManager:
use Bitrix\Main\Event;
use Bitrix\Main\EventManager;
use Bitrix\Main\EventResult;
use Bitrix\Main\Loader;
use Native\Api\Config\Internals\BaseConfig;
use Native\Api\Config\Internals\ModuleEventConfig;
if (Loader::includeModule('native.api')) {
$eventManager = EventManager::getInstance();
// Здесь зарегистрируйте нужные обработчики из примеров ниже.
}Примеры используют события конвейера API. В обработчике $event доступны параметры конкретного события и apiContext. Путь orders ниже — путь выбранного роута без префикса точки входа и крайних слешей. Замените его своим путём.
До IP-проверки роута
Добавим запрещённый адрес для orders, сохранив остальные ограничения роута:
$eventManager->addEventHandler(
BaseConfig::MODULE_ID,
ModuleEventConfig::BEFORE_IP_ACCESS,
static function (Event $event): ?EventResult {
$route = $event->getParameter(ModuleEventConfig::PARAMETER_ROUTE);
if ($route->getPath() !== 'orders') {
return null;
}
$blacklist = $event->getParameter(ModuleEventConfig::PARAMETER_IP_BLACKLIST);
$blacklist[] = '192.0.2.50';
return new EventResult(EventResult::SUCCESS, [
ModuleEventConfig::PARAMETER_IP_BLACKLIST => $blacklist,
]);
},
);Изменение действует на текущую проверку, не сохраняется в карту и не отменяет глобальные ограничения. Обработчик вызывается и при пустых IP-списках роута. Чтобы изменить списки, возвращайте EventResult::SUCCESS: обычный массив означает досрочный ответ клиенту.
После IP-проверки роута
Передадим контроллеру orders проверенный адрес клиента в параметре clientIp. Входящее значение этого параметра заменяется адресом из REMOTE_ADDR:
$eventManager->addEventHandler(
BaseConfig::MODULE_ID,
ModuleEventConfig::AFTER_IP_ACCESS,
static function (Event $event): void {
$route = $event->getParameter(ModuleEventConfig::PARAMETER_ROUTE);
if ($route->getPath() !== 'orders') {
return;
}
$request = $event->getParameter(ModuleEventConfig::PARAMETER_HTTP_REQUEST);
$context = $event->getParameter(ModuleEventConfig::PARAMETER_API_CONTEXT);
$params = $context->getParams();
$params['clientIp'] = $request->getRemoteAddress();
$context->setParams($params);
},
);After вызывается только при успешной IP-проверке. В нём доступны фактически проверенные ipBlacklist и ipWhitelist, включая изменения Before-обработчика. Оба события выполняются до авторизации и чтения кеша ответа. Добавленный clientIp входит в параметры запроса, а значит, учитывается в ключе кеша результата.
До проверки параметров
Уберём пробелы по краям article перед штатной валидацией:
$eventManager->addEventHandler(
BaseConfig::MODULE_ID,
ModuleEventConfig::BEFORE_PARAMETERS,
static function (Event $event): void {
$context = $event->getParameter(ModuleEventConfig::PARAMETER_API_CONTEXT);
$params = $context->getParams();
if (isset($params['article']) && is_string($params['article'])) {
$params['article'] = trim($params['article']);
$context->setParams($params);
}
},
);Возвращать данные не нужно: параметры изменены через общий контекст запроса.
После контроллера
Удалим служебное поле internalComment из результата контроллера orders, прежде чем модуль сохранит результат в кеш и сформирует JSON/XML:
$eventManager->addEventHandler(
BaseConfig::MODULE_ID,
ModuleEventConfig::AFTER_CONTROLLER,
static function (Event $event): ?EventResult {
$route = $event->getParameter(ModuleEventConfig::PARAMETER_ROUTE);
if ($route->getPath() !== 'orders') {
return null;
}
$response = $event->getParameter(ModuleEventConfig::PARAMETER_RESPONSE);
unset($response['internalComment']);
return new EventResult(EventResult::SUCCESS, [
ModuleEventConfig::PARAMETER_RESPONSE => $response,
]);
},
);При попадании в кеш контроллер и его события не выполняются. После добавления такого обработчика очистите ранее сохранённый кеш роута, чтобы в нём не осталось старого поля.
До отправки ответа
Добавим заголовок к уже сформированному HTTP-ответу:
$eventManager->addEventHandler(
BaseConfig::MODULE_ID,
ModuleEventConfig::BEFORE_RESPONSE,
static function (Event $event): void {
$response = $event->getParameter(ModuleEventConfig::PARAMETER_RESPONSE);
$response->addHeader('X-Api-Service', 'native.api');
},
);Здесь response — объект Bitrix\Main\HttpResponse, а в onAfterController — массив данных контроллера. При досрочном ответе из более раннего события onBeforeResponse не вызывается.
Не используйте echo, die или exit в обработчиках для формирования ответа. Возврат обычного массива или HttpResponse завершает конвейер штатно; null и return; продолжают выполнение. Сигнатура : void подходит только обработчикам без возвращаемого значения.