В модулях Битрикс HTTP API удобно собирать на Engine Controller + файл роутов в /local/routes/, а не на россыпи ajax.php. Ядро подхватывает конфиг routing из .settings.php, вызывает action-методы контроллера и само разбирает JSON/фильтры. Ниже — минимальный рабочий каркас и типичные ошибки.
Внутри action входящие данные всё равно приходят из того же HTTP-контекста D7 — см. Application / Context / Request / Response, ServiceLocator для сервисов. Ошибки операции удобно отдавать через контракт Result / Error.
1. Включить routing в .settings.php
В /bitrix/.settings.php или /local/.settings.php добавьте (фрагмент):
'routing' => [
'value' => [
'config' => ['api.php'],
],
'readonly' => false,
],
Битрикс ищет /local/routes/api.php, при отсутствии — /bitrix/routes/api.php. Для кастома держите файл в /local/routes/.
2. Описать маршруты
// /local/routes/api.php
use BitrixMainRoutingRoutingConfigurator;
use MyModuleControllerAuthController;
return static function (RoutingConfigurator $routes) {
$routes->prefix('auth')->group(static function (RoutingConfigurator $routes) {
// POST /api/auth/ → AuthController::checkRequestAction
$routes->post('', [AuthController::class, 'checkRequest']);
});
};
В роуте указываете имя метода без суффикса Action. В классе метод обязан называться checkRequestAction.
3. Контроллер и JSON pre-filter
<?php
namespace MyModuleController;
use BitrixMainEngineController;
use BitrixMainEngineActionFilter;
class AuthController extends Controller
{
protected function getDefaultPreFilters(): array
{
return [
new ActionFilterHttpMethod([ActionFilterHttpMethod::METHOD_POST]),
new ActionFilterContentType([ActionFilterContentType::JSON]),
// при необходимости: new ActionFilterAuthentication(),
// new ActionFilterCsrf(),
];
}
/**
* Ожидает JSON вида:
* { "SubscriptionItems": { "PartialResult": "1", "Count": "10" } }
*/
public function checkRequestAction($SubscriptionItems): array
{
// аргумент = корневой ключ JSON с тем же именем
return is_array($SubscriptionItems) ? $SubscriptionItems : [];
}
}
Имя аргумента action должно совпадать с ключом в JSON. Если шлёте «плоский» объект без обёртки — принимайте через $this->getRequest() / getInput(), а не через магию аргументов.
4. Автозагрузка классов модуля
В include.php модуля зарегистрируйте контроллер (и сервисы):
use BitrixMainLoader;
Loader::registerAutoLoadClasses('my.module', [
MyModuleControllerAuthController::class => 'lib/controller/authcontroller.php',
MyModuleServiceAuthorisationService::class => 'lib/services/AuthorisationService.php',
]);
ID модуля в registerAutoLoadClasses — как в install/index.php (обычно lower-case с точкой: my.module). Пути — относительно корня модуля.
Типичные ошибки
- В роуте написали
checkRequestAction— нужноcheckRequest. - Забыли pre-filter
ContentType::JSONпри JSON-теле — аргументы пустые. - Неверный ID модуля в
registerAutoLoadClasses— class not found. - Роут добавили, кеш/opcache не сбросили — 404 до перезагрузки php-fpm.
- Смешали urlrewrite публички и routing API — разные файлы и разные задачи.
Заключение
Схема короткая: routing в settings → local/routes/api.php → Controller с *Action → автозагрузка в include.php. Так модульный HTTP API остаётся читаемым, а фильтры закрывают method/JSON/auth до бизнес-логики.

