rest · REST API 26.800.0 Ломающее

Rest 26.700.0–26.800.0: отложенная установка приложений, строгий bool в REST 3.0 и вебхуки со сроком действия

2 мин чтения Устаревших API: 2
Узнавайте о ломающих изменениях Битрикса раньше, чем они доедут до прода: свежие разборы — в канале @bxmax_updates

Ломающее обновление

Удалены или изменены публичные API — прикладной код может перестать работать.

В БУС вышли подряд две версии rest: 26.700.0 и 26.800.0. В 26.700.0 у входящих вебхуков появился срок действия, а сотрудник без права установки может попросить администратора поставить приложение. В 26.800.0 поменялось время срабатывания OnRestAppInstall, REST 3.0 стал строже проверять входные данные, и появился каркас событий REST 3.0. Обработчики установки приложений и клиенты REST 3.0 стоит проверить до обновления.

Новое

Вебхук со сроком действия (26.700.0)

У входящего вебхука появилось поле DATE_EXPIRE. В REST 3.0 при создании можно передать dateExpire в формате Y-m-d, не раньше сегодняшнего дня. Дату сдвигает новый метод rest.incomingwebhook.prolong (имя по схеме REST 3.0, это IncomingWebhook::prolongAction). В день DATE_EXPIRE вебхук ещё работает, а на следующий день первый же запрос не проходит авторизацию, и вебхук получает ACTIVE = N. Продление включает его обратно, а сократить срок нельзя. Продлить бессрочный вебхук или вебхук, отключённый вручную, тоже нельзя. Оба случая дают CannotProlongIncomingWebhookException, попытка сократить срок даёт CannotReduceIncomingWebhookExpirationException.

Из PHP вебхук продлевает публичная команда. run() у команд main заворачивает исключение обработчика в CommandException, так что причину отказа берите из getPrevious():

        <?php declare(strict_types=1);

namespace Vendor\Integration\Webhook;

use Bitrix\Main\Command\Exception\CommandException;
use Bitrix\Main\Loader;
use Bitrix\Main\Type\Date;
use Bitrix\Rest\Internal\Exception\IncomingWebhook\CannotProlongIncomingWebhookException;
use Bitrix\Rest\Public\Command\IncomingWebhook\ProlongIncomingWebhookCommand;

final class WebhookProlonger
{
    public function prolong(int $userId, string $password, int $days = 30): bool
    {
        Loader::requireModule('rest');

        try {
            (new ProlongIncomingWebhookCommand(
                userId: $userId,
                webHookPassword: $password,
                dateExpire: (new Date())->add("+{$days} days"),
            ))->run();
        } catch (CommandException $e) {
            if ($e->getPrevious() instanceof CannotProlongIncomingWebhookException) {
                return false;
            }

            throw $e;
        }

        return true;
    }
}

    

$userId здесь пользователь, от имени которого проверяется право управлять вебхуком.

Запросы на установку приложений (26.700.0)

Сотрудник без права установки отправляет запрос из карточки приложения в Маркете. Интерфейс мы разобрали в market 26.200.0–26.200.100. rest хранит запросы в b_rest_app_install_request и шлёт уведомления в IM: автору сообщает, что запрос ушёл, каждому администратору присылает карточку со ссылкой на установку. Кнопка «Перейти к установке» открывает страницу установки и одновременно убирает карточку у остальных администраторов, сам approveAction ничего не ставит. Когда версия установлена, обработчик OnRestAppInstall закрывает все ожидающие запросы на неё.

Для своего кода есть публичные CreateAppInstallRequestCommand, RejectAppInstallRequestCommand и AppInstallRequestProvider::hasActivePendingRequest(). Запрос не создаётся, если у пользователя уже есть ожидающий запрос на эту версию, версия уже установлена или пользователь может поставить её сам.

Режим завершения установки (26.800.0)

Приложение хранит режим INSTALL_COMPLETION_MODE: immediate (установлено сразу) или deferred (ждёт, пока приложение само подтвердит установку). Если режим не задан, immediate получают приложения с пустым URL установки и приложения «только API», остальные получают deferred. Методы REST 3.0 для установки локального и персонального приложения принимают installUrl и installCompletionMode:

        {
  "title": "Склад",
  "handlerUrl": "https://app.example.com/",
  "installUrl": "https://app.example.com/install",
  "installCompletionMode": "deferred",
  "scopes": ["crm"],
  "menuTitles": {"ru": "Склад"}
}

    

В режиме deferred ответ приходит с oauthToken: null, а в данных приложения нет clientSecret и applicationToken. В форме интеграции режим задаёт флажок «Приложение само завершает установку».

Событие onRestAccessGrant (26.800.0)

Проверки доступа к REST теперь идут цепочкой стратегий, и в цепочку встроено событие rest:onRestAccessGrant. Оно приходит, когда запрос отклонён по тарифу (reason = tariff) или из-за подписки Маркета (market_subscription), с параметрами authType, clientId, passwordId и method. Если обработчик вернул EventResult::SUCCESS, запрет снимается.

Сертификаты УЦ Минцифры (26.800.0)

Новая опция модуля trust_national_ca, по умолчанию включённая для лицензий региона ru, добавляет корневой сертификат Минцифры в доверенные для запросов, созданных через HandlerHttpFactory. В ядре это пока загрузка формы настроек приложения и REST-обработчики платёжных систем и онлайн-касс sale. Системное хранилище сертификатов при этом не меняется. Для своих интеграций вызывайте тот же HandlerHttpFactory::create(), он возвращает обычный HttpClient с этим сертификатом в SSL-контексте:

        <?php declare(strict_types=1);

use Bitrix\Main\Loader;
use Bitrix\Rest\Public\Provider\Application\HandlerHttpFactory;

Loader::requireModule('rest');

$http = HandlerHttpFactory::create(['socketTimeout' => 5, 'streamTimeout' => 15]);
$status = $http->get('https://partner.example.ru/api/status');

    

Если после загрузки фрейма приложение за 3 секунды не вышло на связь, app.layout проверяет хост и показывает заглушку с причиной: сертификат Минцифры, самоподписанный сертификат или сервер не отвечает. В заглушке есть отдельная подсказка для Firefox и кнопка «Открыть в новой вкладке».

Каркас событий REST 3.0 (26.800.0)

Появились реестр событий, метод списка событий и онлайн-подписка с selectFields, filterFields и updateFields. Модуль объявляет провайдеров событий в .settings.php, в секции rest → events → providers. Подписки хранятся в b_rest_event с VERSION = 3. Подписаться пока не на что, единственный провайдер в ядре возвращает пустой список.

Что сломается

Проверьте обработчики OnRestAppInstall (26.800.0)

Раньше установка из Маркета и CRestUtil::InstallApp() сразу вызывали AppTable::install(), а с ним и обработчики rest:OnRestAppInstall. Так было даже для приложения с URL установки, которое ещё не подтвердило её (INSTALLED = N). Теперь в режиме deferred событие приходит только после того, как приложение завершит установку. Конфигурации (кроме режима сайта) и BI-дашборды из Маркета всегда получают deferred. Новое локальное приложение тоже получает событие при создании только в режиме immediate. Если ваш обработчик ловил начало установки, для таких приложений этого вызова больше не будет.

Для неустановленного приложения (INSTALLED = N) ApplicationProvider::getByClientId() теперь возвращает null, а ApplicationProvider::getOAuthToken() бросает AccessDeniedException, даже для администратора.

REST 3.0 строже проверяет входные данные (26.800.0)

  • Поля bool принимают только true/false и 0/1. Строка "N" раньше молча превращалась в true и включала флаг, теперь клиент получит InvalidRequestFieldTypeException.
  • Отрицательные pagination.limit и offset теперь дают InvalidPaginationException (нулевой limit отклонялся и раньше).
  • handlerUrl и installUrl при установке приложения должны начинаться с http:// или https://. В коде так закрыт stored XSS через javascript: и data:.

Форма настроек приложения проверяет права (26.800.0)

AppForm::getConfigAction() теперь проверяет доступ к приложению. Раньше любой авторизованный пользователь мог заставить портал отправить на URL_SETTINGS приложения событие со своей авторизацией и refresh-токеном. Теперь без доступа он получит ACCESS_DENIED.

Проверьте вызовы CreateIncomingWebhookCommand (26.700.0)

В конструкторе команды новый параметр ?Date $dateExpire стоит перед $ownerUserId. Код, который создаёт вебхук этой командой и передаёт ownerUserId шестым позиционным аргументом, получит TypeError. С именованными аргументами всё работает.

БД

В 26.800.0 в b_rest_event добавлены JSON_OPTIONS и VERSION (по умолчанию 1), уникальный индекс теперь включает VERSION. Старые event.bind, event.get и отправка событий фильтруют VERSION = 1, в своих запросах к таблице делайте так же.

В b_rest_app появилась колонка INSTALL_COMPLETION_MODE, NOT NULL со значением по умолчанию deferred. После обновления посмотрите, какой режим получили старые локальные приложения:

        <?php declare(strict_types=1);

use Bitrix\Main\Loader;
use Bitrix\Rest\AppTable;

Loader::requireModule('rest');

$apps = AppTable::getList([
    'select' => ['ID', 'CODE', 'URL_INSTALL', 'INSTALL_COMPLETION_MODE'],
    'filter' => ['=STATUS' => AppTable::STATUS_LOCAL],
])->fetchAll();

    

Скрипта, который проставлял бы режим существующим записям, в отчёте нет, но его может выполнить апдейтер. Если все старые приложения остались deferred, API-only приложение при переустановке останется неустановленным и без события, а в форме интеграции флажок «Приложение само завершает установку» окажется включён.

В 26.700.0 схема не менялась. b_rest_ap.DATE_EXPIRE и b_rest_app_install_request объявлены ещё в rest 26.650.0, теперь к ним есть ORM.

Мелочи и находки

  • Продление вебхука повторяет проверки в WHERE самого UPDATE: если вебхук отключили между чтением и записью, строка не обновится. Для этого в модуле появился трейт с updateByFilter(), массовым UPDATE по ORM-фильтру, который отказывается работать с пустым фильтром (26.700.0).
  • PasswordParser разбирает URL вебхука REST 3.0 вида /rest/api/<user>/<password>/. Старый код в request-классах брал из такого URL не тот сегмент (26.700.0).
  • placement.bind больше не оставляет висеть блокировку, если запись встройки упала с исключением, а конфликт уникального индекса b_rest_placement возвращает ERROR_EMBEDDING_HANDLER_ALREADY_BOUND вместо ошибки SQL (26.800.0).

Устаревшие и удалённые API в этой версии

Символ Статус Чем заменять
Bitrix\Rest\Infrastructure\Rest\Request\DeleteIncomingWebhookRequest::getWebhookPassword() Удалено Bitrix\Rest\Internal\Service\IncomingWebhook\PasswordParser::parse()
Bitrix\Rest\Infrastructure\Rest\Request\UpdateIncomingWebhookRequest::getWebhookPassword() Удалено Bitrix\Rest\Internal\Service\IncomingWebhook\PasswordParser::parse()

Новая версия вышла — разбор уже в Telegram

В канале @bxmax_updates публикуем каждый свежий разбор: что сломается, что устарело и что появилось в API. Узнаете до того, как обновите прод.

Подписаться

Читайте дальше

rest 26.600.0 Ломающее Свежее

Rest 26.600.0: отложенный batch и Idempotency-Key в REST V3, новые правила для встроек

В `rest` 26.600.0 (сборка от 23.07.2026) 143 файла и +5143/−383 строк. В REST V3 появились отложенный batch со своей таблицей и очередью, идемпотентность по заголовку `Idempotency-Key` и перечисления, значения которых берутся из кода. Заодно переделали права на встройки и сигнатуры команд встроек. К…

1 мин
rest 26.650.0 Ломающее Свежее

Rest 26.650.0: тарифные ограничения Vibe+ и установка приложений через блокировку

`rest` 26.650.0 (сборка от 06.08.2026, 78 файлов, +3003/−371 строк) почти целиком про тарифные ограничения REST для модели монетизации Bitrix24 «Vibe+». Тарифные решения принимаются по данным модуля `bitrix24`, и на коробке без него ограничения не включаются. Часть изменений касается всех редакций:…

1 мин
rest 26.500.0 Безопасность

rest 26.500.0: журнал аудита безопасности и курсорные ответы в V3

REST завёл единый журнал того, что происходит с приложениями, правами и вебхуками, а установщик переехал с SQL-батчей на миграции ядра. Публичные REST-методы не тронуты — ломается внутреннее и V3-API, так что читать этот разбор стоит тем, кто пишет свои модули поверх `rest`, а не тем, кто дёргает `c…

3 мин
socialnetwork 26.200.0 Безопасность Свежее

Socialnetwork 26.200.0: XSS в заявках и списке участников, копирование проекта по праву редактирования и курсор в log.blogpost.get

Socialnetwork 26.200.0 закрывает XSS в списке участников проекта и в заявках в группы, подмену ссылок через название группы и утечку задач в контекст AI. Копировать проект теперь можно только с правом на редактирование. Администраторам, у которых стояли 26.100.0 или 26.150.0, стоит проверить права с…

2 мин
Мы используем файлы cookie для улучшения работы сайта. Продолжая использовать сайт, вы соглашаетесь с нашей политикой конфиденциальности.
AI Домовой

AI Домовой История

на связи

пишет…
Нет истории чатов
AI Домовой

Нужна авторизация

Войдите, чтобы задавать вопросы AI Домовому.

Войти