В практике разработки на платформе 1С:Предприятие 8.3 иногда возникают ситуации, когда необходимо вызвать программный код, расположенный внутри модуля HTTP-сервиса, из другого места системы — например, из внешней обработки или регламентного задания. Ситуация осложняется, если архитектура системы «унаследована» и внесение изменений в основную конфигурацию ограничено требованиями заказчика или владельца базы.
В данной статье мы разберем технические особенности модулей HTTP-сервисов, проанализируем, почему стандартные методы обращения не работают, и рассмотрим три надежных способа решения задачи, включая «обходные пути» для закрытых конфигураций.
Для начала проанализируем устройство платформы. Модуль HTTP-сервиса не является глобальным. В отличие от общих модулей с флагом Глобальный или модулей менеджеров объектов, к нему нельзя обратиться по имени сервиса. Даже если процедура помечена ключевым словом Экспорт, она остается доступной только внутри контекста самого сервиса в момент обработки входящего запроса.
У объекта HTTPСервис в метаданных отсутствует метод Создать() или возможность получить экземпляр объекта программно. Платформа инициализирует этот модуль автоматически только тогда, когда на публикацию базы приходит соответствующий HTTP-вызов. Таким образом, даже если вы знаете имя процедуры, вызов вида HTTPСервисы.МойСервис.МояПроцедура() вызовет ошибку компиляции.
Рассмотрим подробнее варианты решения этой проблемы в зависимости от ваших прав доступа к коду.
Если вы не являетесь «хозяином базы» и вам запрещено править основную конфигурацию, использование расширений — это самый профессиональный и безопасный путь. Рассмотрим этот алгоритм по шагам:
рш_ОбщийМодульСервисов) с флагами Сервер и Вызов сервера.Теперь нужная логика доступна из любой точки системы через обращение к рш_ОбщийМодульСервисов.НужнаяПроцедура(), а HTTP-сервис продолжает работать в штатном режиме, используя «проброс» вызова. Для ускорения разработки типовой структуры процедур можно использовать готовый общий модуль для организации HTTP-сервиса.
Если создание расширений по каким-то причинам невозможно, проанализируем вариант имитации внешнего вызова. Это наиболее честный способ с точки зрения платформы, так как код будет выполнен именно в том контексте, для которого он предназначался. Для интерактивной проверки и отладки подобных запросов подойдёт обработка для тестирования HTTP-сервисов методом GET и POST.
Для этого мы можем программно выполнить HTTP-запрос к текущей информационной базе. Разберем пример кода для такого вызова:
// Определяем параметры подключения к текущей базе
Сервер = "localhost"; // или имя сервера в сети
Порт = 80;
Пользователь = "Администратор";
Пароль = "password";
Соединение = Новый HTTPСоединение(Сервер, Порт, Пользователь, Пароль);
Запрос = Новый HTTPСервисЗапрос("hs/v1/my_method/");
// Если процедуре нужны параметры, передаем их в теле или заголовках
Запрос.УстановитьТелоИзСтроки(ДанныеДляОбработкиВФорматеJSON);
Попытка
Ответ = Соединение.ВызватьHTTPМетод("POST", Запрос);
Если Ответ.КодСостояния = 200 Тогда
// Процедура успешно отработала
КонецЕсли;
Исключение
// Обработка ошибок связи
КонецПопытки;
Важный нюанс: при таком методе создается новый сеанс. Это означает, что ПараметрыСеанса, временные таблицы или переменные вашего текущего сеанса не будут доступны внутри вызываемой процедуры. Все необходимые данные нужно передавать явно через структуру запроса.
Как было предложено в обсуждении, если стоит задача разового или периодического вызова куска кода, можно воспользоваться методом выноса логики во внешнюю обработку. Выясним причину, почему это не всегда просто сделать «в лоб».
Процедуры в HTTP-сервисах часто жестко завязаны на объект типа HTTPСервисЗапрос. Этот объект содержит заголовки, параметры URL и тело запроса. При простом копировании кода в модуль обработки вы столкнетесь с ошибками неопределенных переменных.
Рассмотрим, как правильно адаптировать код при переносе в обработку:
Запрос (например, Запрос.ПараметрыURL).HTTPСервисЗапрос на универсальный тип Структура или Соответствие.Пример адаптации кода:
// В модуле внешней обработки
ПараметрыДляВызова = Новый Структура;
ПараметрыДляВызова.Вставить("ИдентификаторОбъекта", "12345");
ПараметрыДляВызова.Вставить("Данные", МоиДанные);
// Вызов процедуры, скопированной из сервиса
ВыполнитьОбработкуДанных(ПараметрыДляВызова);
// Сама процедура (адаптированная)
Процедура ВыполнитьОбработкуДанных(ВходящиеДанные)
// Вместо Запрос.ПараметрыURL["id"] используем:
Идентификатор = ВходящиеДанные.ИдентификаторОбъекта;
// ... логика обработки ...
КонецПроцедуры
Подведем итоги анализа ситуации. Прямой вызов экспортной процедуры из модуля HTTP-сервиса платформой не предусмотрен. Если вы столкнулись с такой необходимостью, это всегда сигнал о том, что бизнес-логика слишком сильно «привязана» к транспортному уровню (HTTP).
Рекомендации по выбору метода:
HTTPСоединение к самому себе.Помните, что чтение текста модуля через метаданные (рефлексия) в среде 1С в режиме «Предприятие» невозможно — платформа скрывает исходный код для защиты интеллектуальной собственности и оптимизации производительности. Поэтому всегда выбирайте один из описанных выше способов обхода ограничений.