1С Битрикс · 5 мин чтения

Свой REST API на Битрикс: отдаём данные сайта во внешнюю систему

Свой 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 ₽/мес.

Есть задача?

Обсудим в мессенджере

Расскажите, что нужно сделать — отвечу в течение 4 часов в рабочее время. Первая консультация бесплатно.

Продолжая пользование настоящим сайтом Вы выражаете своё согласие на обработку Ваших персональных данных (файлов куки) с использованием Yandex.Metrika.
Понятно