Как использовать Конструктор запросов 1С для внешних баз через HTTP-сервисы?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Довольно часто перед разработчиками встает задача создания инструментов для консолидации данных из нескольких удаленных информационных баз. Разберем интересную ситуацию: у нас есть обработка, отправляющая запросы к удаленным базам через HTTP-сервисы. Текст запроса пишется вручную, но мы хотим упростить жизнь пользователям и дать им возможность использовать стандартный визуальный конструктор запросов, чтобы он показывал структуру удаленной базы. Выясним причину, почему это не работает "из коробки", и подробно проанализируем доступные пути решения этой архитектурной задачи.

Ограничения платформы 1С и текущий контекст

Первое, что мы должны понимать — стандартный КонструкторЗапросов в платформе 1С:Предприятие имеет жесткую привязку к метаданным текущей информационной базы, то есть к объекту Метаданные. Платформа физически не позволяет программно передать в этот визуальный интерфейс "чужое" дерево метаданных из внешнего источника. Конструктор всегда будет показывать только те справочники, документы и регистры, которые существуют в конфигурации, где он был запущен.

Рассмотрим подробнее несколько практических подходов, которые помогут нам обойти это ограничение и реализовать удобную работу с запросами для внешних баз.

Решение 1: Использование базы-донора (при идентичных конфигурациях)

Если ваши базы имеют одинаковую структуру (например, это узлы РИБ или просто клоны одной конфигурации), мы можем воспользоваться самым простым и логичным путем. Нам не нужно пытаться загрузить метаданные из удаленного узла.

Посмотрим на алгоритм действий в этом случае:

  1. Открываем обработку с конструктором в той базе, где структура совпадает с целевыми базами.
  2. Составляем запрос визуально, выбирая локальные таблицы.
  3. Полученный текст запроса передаем в виде строки через тело HTTP-запроса на удаленный сервер.
  4. На стороне HTTP-сервиса удаленной базы принимаем строку, выполняем запрос и возвращаем результат в формате JSON.

Этот метод работает идеально, но только до тех пор, пока структуры баз идентичны. Если текущая конфигурация отличается от базы-источника, этот подход применять нельзя.

Решение 2: Внешние источники данных (ВИД)

Проанализируем ситуацию, когда структуры баз отличаются. Как заставить конструктор увидеть чужие таблицы? Мы можем задействовать механизм Внешние источники данных.

Этот механизм позволяет подключаться к сторонним базам данных (в том числе к другим базам 1С) на уровне SQL-запросов через ODBC или ADO. Разберем по шагам:

  1. Настраиваем строку подключения к SQL-серверу целевой информационной базы в дереве метаданных в ветке "Внешние источники данных".
  2. Синхронизируем нужные таблицы (выбираем таблицы справочников, документов и т.д., к которым планируем обращаться).
  3. После этого добавленные таблицы внешней базы появляются в стандартном конструкторе на закладке "Внешние источники данных".

Теперь мы можем визуально собирать запрос. Текст запроса будет валиден для текущей базы. Важно: в этом случае данные извлекаются напрямую из SQL, в обход HTTP-сервиса удаленной базы 1С. Если обязательным требованием является использование именно HTTP-сервисов, перейдем к следующему варианту.

Решение 3: Программная генерация через объект "СхемаЗапроса"

Если мы хотим остаться в рамках HTTP-взаимодействия и не имеем доступа к прямому SQL-соединению, нам потребуется реализовать свой собственный мини-конструктор. Начиная с версии платформы 8.3.5, у нас появился мощнейший объект СхемаЗапроса.

Разберем, как это реализовать:

  1. В удаленной базе создаем метод HTTP-сервиса (GET или POST), который собирает дерево метаданных (перебирает Метаданные.Справочники, Метаданные.Документы и их реквизиты) и возвращает эту структуру в формате JSON.
  2. В локальной базе обработки вызываем этот сервис, получаем JSON и строим на форме элемент ДеревоЗначений. Это будет визуальная замена стандартному дереву таблиц конструктора.
  3. Пользователь отмечает галочками нужные поля в этом дереве.
  4. Мы программно обходим выбранные строки и с помощью объекта СхемаЗапроса формируем текст запроса.

Посмотрим на пример того, как программно добавить поле в выборку через схему:


Схема = Новый СхемаЗапроса;
Пакет = Схема.ПакетЗапросов[0];
Оператор = Пакет.Операторы[0];

// Добавляем таблицу источника
Источник = Оператор.Источники.Добавить("Справочник.Номенклатура", "Номенклатура");

// Добавляем поля
Оператор.ВыбираемыеПоля.Добавить("Номенклатура.Ссылка");
Оператор.ВыбираемыеПоля.Добавить("Номенклатура.Наименование");

ТекстСгенерированногоЗапроса = Схема.ПолучитьТекстЗапроса();

После получения текста ТекстСгенерированногоЗапроса, мы отправляем его на выполнение через HTTP-сервис в удаленную базу.

Вопросы безопасности: Опасность передачи текста запроса

Проанализируем крайне важный архитектурный аспект, о котором часто забывают. Выполнение произвольного текста запроса, пришедшего извне (через HTTP) — это огромная дыра в безопасности. Это классическая уязвимость.

Риски передачи "сырого" текста запроса:

  1. Угроза производительности: злоумышленник или неопытный программист может написать запрос с декартовым произведением огромных таблиц без условий соединений, что мгновенно "повесит" сервер целевой базы.
  2. Утечка данных: можно написать запрос к таблицам с конфиденциальной информацией (например, к регистру сведений с зарплатой или параметрами авторизации), обойдя интерфейсные ограничения.

Как сделать правильно?
Вместо передачи сырого текста запроса, рекомендуется передавать структурированные параметры фильтрации (например, структуру с именами полей и значениями отборов). На стороне базы-приемника (в модуле HTTP-сервиса) должен быть жестко запрограммированный безопасный запрос, в который просто подставляются пришедшие параметры. Если же требуется именно произвольная выборка, необходимо реализовать жесткий парсинг входящего текста запроса или использовать объект СхемаЗапроса на стороне сервера для валидации выбранных таблиц и полей перед выполнением.

Итоги

Мы подробно рассмотрели проблему работы с Конструктором запросов для удаленных баз. Как мы выяснили, платформа не позволяет "подсунуть" чужие метаданные в стандартное окно конструктора. Однако мы можем элегантно обойти это ограничение: либо используя идентичную конфигурацию для генерации текста, либо подключая таблицы через Внешние источники данных, либо создавая собственный интерфейс выбора полей с программной сборкой текста с помощью объекта СхемаЗапроса. Главное при реализации обмена через HTTP — всегда помнить о безопасности и не допускать бесконтрольного выполнения произвольного кода на стороне сервера-приемника.

← На главную