Свой REST API на Битрикс я собираю почти в каждом проекте, где сайту нужно делиться данными с внешним миром без встроенного модуля обмена или полноценного REST-приложения из Маркетплейса. Стандартный REST-модуль Битрикс рассчитан на публичные приложения: с регистрацией, OAuth и правами по scope. Для внутренней задачи, вроде выгрузки остатков в СДЭК, синхронизации заказов с ботом на aiogram или сценария в n8n, это избыточно. Проще зарегистрировать один-два собственных метода и отдавать через них ровно тот срез данных, который нужен внешней системе, без лишних полей и прав.
Когда нужен свой REST-эндпоинт на сайте Битрикс
На практике запрос на кастомный REST-метод приходит в похожих ситуациях.
- мобильное приложение читает каталог и остатки напрямую из ядра сайта, без промежуточных выгрузок в XML или CSV;
- 1С обменивается с сайтом не по стандартному CommerceML, а по своей логике, например забирает только заказы за последний час;
- Telegram-бот на aiogram запрашивает статус заказа по номеру телефона и присылает клиенту ответ в чат;
- сценарий в n8n раз в час опрашивает сайт и раскидывает новые заявки по отделам через вебхуки CRM;
- партнёрский сайт получает у себя актуальные цены и наличие для собственного прайса.
Во всех этих случаях городить полноценное REST-приложение с регистрацией в Маркетплейсе смысла нет: данные нужны одному конкретному потребителю, а не произвольному внешнему разработчику. Достаточно метода, который проверяет токен и отдаёт JSON нужной формы.
Два способа подключить REST-обработчик к сайту
Первый способ, встроиться в штатный механизм модуля rest через событие OnRestServiceBuildDescription. Метод попадает в общий реестр REST Битрикс, доступен по адресу /rest/имя.метода и может работать с авторизацией модуля из коробки.
Второй способ, отдельный PHP-файл в корне сайта. Подключаю пролог ядра, сам проверяю токен из GET-параметра или заголовка, сам формирую ответ. Никакого реестра методов, зато результат готов за полчаса.
| Критерий | Событие rest | Отдельный PHP-файл |
|---|---|---|
| Время на первый метод | 2-3 часа с учётом разбора API | 30-60 минут |
| Авторизация из коробки | вебхуки, OAuth, права пользователя модуля rest | пишу проверку токена вручную |
| Виден в стандартном списке REST-методов | да | нет |
| Подходит для приложения из Маркетплейса | да | нет, только для внутренней задачи |
Для разовой интеграции с одним конкретным сервисом обычно беру второй вариант, он предсказуемее и проще в отладке. Если метод в будущем может понадобиться нескольким внешним системам или самому Битрикс24, регистрирую его через событие.
Регистрирую REST-метод через OnRestServiceBuildDescription
Обработчик вешаю в local/php_interface/init.php, а логику метода выношу в отдельный класс, чтобы не захламлять init.
AddEventHandler('rest', 'OnRestServiceBuildDescription', 'KalinkindevRestInit');
function KalinkindevRestInit()
{
return [
'kalinkindev' => [
'kalinkindev.orders.get' => 'KalinkindevRestOrders::get',
],
];
}
Имя метода принято составлять из двух частей через точку: условный код проекта и действие. Это чисто соглашение Битрикс, но если его нарушить, метод всё равно подключится, просто будет плохо читаться в общем списке.
Что Битрикс передаёт в обработчик
В метод приходят параметры запроса, номер страницы для пагинации и объект сервера. Внутри проверяю токен и забираю данные через D7 ORM.
class KalinkindevRestOrders
{
public static function get($arParams, $n, $server)
{
$token = $arParams['token'] ?? '';
if ($token !== \COption::GetOptionString('kalinkindev.rest', 'access_token')) {
throw new \Bitrix\Rest\RestException('Access denied', 'ACCESS_DENIED', \CRestServer::STATUS_FORBIDDEN);
}
$result = [];
$res = \Bitrix\Sale\OrderTable::getList([
'filter' => ['STATUS_ID' => 'N'],
'select' => ['ID', 'ACCOUNT_NUMBER', 'PRICE', 'DATE_INSERT'],
'limit' => 50,
]);
while ($order = $res->fetch()) {
$result[] = $order;
}
return $result;
}
}
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
Настраиваю авторизацию: вебхук или локальное приложение
Если метод зарегистрирован через событие, можно встроиться в локальный OAuth-сервер модуля rest: создать локальное приложение на вкладке разработчика, получить client_id и client_secret и авторизовать запросы токеном. Это уместно, когда данные забирает не один сервис, а несколько, и нужен полноценный контроль прав по scope.
Для интеграции с одним конкретным внешним сервисом чаще делаю проще: генерирую длинный случайный токен, кладу его в опции модуля через COption::SetOptionString и сверяю на входе каждого запроса. Никакого обращения к OAuth-серверу, никакой лишней логики, только заголовок или GET-параметр с токеном и сравнение строк. Такой способ проще отлаживать и проще передать на сторону n8n или Telegram-бота, где токен просто хранится в переменной окружения.
Если работу над таким эндпоинтом отдаёте на сторону, а не пишете сами, разумно сразу закладывать разработку кастомных REST-интеграций отдельной задачей в смете проекта, а не пытаться встроить её в общий бюджет доработки сайта.
Отдаю данные каталога и заказов в JSON
Если метод не завязан на реестр REST и работает как отдельный файл, структура получается компактнее.
define('NO_KEEP_STATISTIC', true);
define('NOT_CHECK_PERMISSIONS', true);
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');
header('Content-Type: application/json; charset=utf-8');
if ($_GET['token'] !== \COption::GetOptionString('kalinkindev.rest', 'access_token')) {
http_response_code(403);
die(json_encode(['error' => 'Access denied']));
}
$res = \Bitrix\Iblock\ElementTable::getList([
'filter' => ['IBLOCK_ID' => 5, 'ACTIVE' => 'Y'],
'select' => ['ID', 'NAME', 'CODE'],
'limit' => 100,
]);
$items = [];
while ($row = $res->fetch()) {
$items[] = $row;
}
echo json_encode($items, JSON_UNESCAPED_UNICODE);
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php');
В выборку включаю только те поля, которые реально нужны потребителю. Для интеграции с СДЭК это обычно вес, габариты и код товара, для Telegram-бота, номер заказа и статус. Если в ответе оказываются телефон или email клиента, храню и передаю такие данные только через серверы в РФ и только тому сервису, которому они действительно нужны по задаче, это требование 152-ФЗ по локализации персональных данных, а не моя прихоть.
Ограничиваю нагрузку и логирую обращения к API
Эндпоинт, который дёргают раз в минуту из n8n или бота, быстро превращается в источник лишней нагрузки на инфоблоки, если каждый запрос идёт напрямую в базу. На такие методы ставлю кэш через CPHPCache на 30-60 секунд, этого достаточно, чтобы сгладить пики и не потерять актуальность данных.
Отдельно веду лог обращений: IP, токен, время запроса, код ответа. Пишу либо в отдельную таблицу через простой INSERT, либо в файл, который потом смотрю при разборе инцидентов. Если у эндпоинта один известный потребитель, дополнительно ограничиваю доступ по IP на уровне .htaccess, это не отменяет проверку токена, а страхует на случай его утечки.
Частые вопросы
Чем свой REST-эндпоинт отличается от штатного REST API Битрикс
Штатный REST рассчитан на публичные приложения из Маркетплейса: с регистрацией, OAuth-сервером и правами по scope. Свой эндпоинт, это один-два метода под конкретную задачу, без выхода в публичный реестр и без лишней инфраструктуры вокруг авторизации.
Нужно ли регистрировать приложение для внутренней интеграции
Если данные забирает один известный сервис, например бот или сценарий в n8n, регистрация локального приложения через OAuth не обязательна. Достаточно собственной проверки токена внутри метода.
Как ограничить доступ к эндпоинту только для одного внешнего сервиса
Сочетаю длинный случайный токен, который сверяю в коде, с ограничением по IP на уровне веб-сервера. Токен закрывает подбор адреса, IP-фильтр закрывает утечку токена.
Сколько стоит разработка кастомного REST-эндпоинта на Битрикс
Зависит от количества методов и глубины интеграции. Простой метод, отдающий один список из инфоблока, обычно укладывается в несколько часов работы, а интеграция с фильтрацией прав, кэшированием и логированием требует отдельной оценки по задаче. Начинаю такие проекты с консультации от 3 000 ₽, чтобы оценить объём, а сопровождение эндпоинта после запуска веду по тарифу техподдержки от 15 000 ₽/мес.