Как передать параметры в GET-запросе в 1С с помощью структуры или другого объекта?

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

При работе с внешними API часто возникает задача выполнить GET-запрос с набором динамических параметров. В 1С для этого используются объекты HTTPСоединение и HTTPЗапрос. Для новичков, желающих закрепить базовые навыки, существует интерактивный обучающий курс по работе с HTTP-запросами, где подробно разбираются GET, POST и другие методы. Однако, в отличие от формирования тел запросов в формате JSON или XML, стандартные средства платформы не предоставляют прямого способа передать параметры GET-запроса в виде структуры или соответствия. Требуется самостоятельно сформировать строку URL с параметрами.

Рассмотрим, как это сделать правильно и какие подходы существуют для упрощения этой задачи, чтобы не "изобретать велосипед" в каждом новом запросе — для этого подойдёт обработка для логирования и анализа HTTP-запросов.

Решение 1: Стандартный подход — ручное формирование строки

Самый прямой и очевидный способ — это собрать строку URL с параметрами вручную. Этот метод подходит для простых запросов, где параметры статичны или их немного. Вся строка с параметрами передается непосредственно при создании объекта HTTPЗапрос. Подобная ручная сборка часто применяется, когда нужно реализовать передачу GUID клиента через параметры GET-запроса или другие специфические заголовки в веб-клиенте.

Посмотрим на пример. Допустим, нам нужно обратиться к API по адресу https://api.jde.ru/vD/calculator/price со следующими параметрами:

В коде 1С это будет выглядеть так:


АдресСервера = "api.jde.ru";
// Все параметры соединяются в одну строку через "&"
СтрокаПараметров = "from=1125899906842658&to=1125899906842673&weight=12&width=1&volume=1&type=1";
// Строка параметров добавляется к адресу ресурса после знака "?"
АдресРесурса = "/vD/calculator/price?" + СтрокаПараметров;

Соединение = Новый HTTPСоединение(АдресСервера, , , , , , Новый ЗащищенноеСоединениеOpenSSL());
Запрос = Новый HTTPЗапрос(АдресРесурса);

Попытка
    Ответ = Соединение.Получить(Запрос);
    КодСостояния = Ответ.КодСостояния;
    // Дальнейшая обработка ответа...
Исключение
    ОписаниеОшибки = ОписаниеОшибки();
    // Обработка исключения...
КонецПопытки;

Преимущества: простота и наглядность для фиксированных запросов.

Недостатки: неудобно при большом количестве динамических параметров, легко допустить ошибку при конкатенации строк, код становится громоздким.

Решение 2: Вспомогательная функция для сборки строки параметров

Чтобы сделать код более читаемым, гибким и универсальным, лучшей практикой является создание собственной вспомогательной функции. Эта функция будет принимать на вход структуру или соответствие с параметрами и возвращать готовую для использования строку. Такой подход важен, если вы строите надежную систему интеграции 1С с внешними сервисами, такими как Google Таблицы, где параметры запроса могут быть многочисленными и сложными.

Ключевой момент, который необходимо учесть, — это кодирование значений параметров. Если значение параметра может содержать пробелы, кириллические символы или спецсимволы (&, =, ?, /), их необходимо преобразовать в безопасный для URL формат с помощью функции URLЗакодировать(). В противном случае сервер может неверно интерпретировать запрос.

Разберем по шагам создание такой функции:

  1. Функция принимает на вход структуру с параметрами.
  2. В цикле перебираются все элементы структуры.
  3. Для каждого элемента формируется строка вида "Ключ=Значение". Значение предварительно кодируется.
  4. Все полученные строки добавляются в массив.
  5. Массив соединяется в одну строку с разделителем &.

Посмотрим на пример реализации такой функции:


&НаСервереБезКонтекста
Функция СформироватьСтрокуПараметров(СтруктураПараметров)
    
    Если СтруктураПараметров = Неопределено Или СтруктураПараметров.Количество() = 0 Тогда
        Возврат "";
    КонецЕсли;
    
    МассивПараметров = Новый Массив;
    
    Для Каждого Элемент Из СтруктураПараметров Цикл
        // Кодируем значение, чтобы избежать проблем со спецсимволами
        ЗакодированноеЗначение = URLЗакодировать(Строка(Элемент.Значение));
        МассивПараметров.Добавить(Элемент.Ключ + "=" + ЗакодированноеЗначение);
    КонецЦикла;
    
    // Соединяем все элементы массива в одну строку через "&"
    Возврат СтрСоединить(МассивПараметров, "&");
    
КонецФункции

Теперь использование этой функции делает основной код намного чище и понятнее:


// 1. Готовим параметры в удобном виде - в виде структуры
ПараметрыЗапроса = Новый Структура;
ПараметрыЗапроса.Вставить("from", "1125899906842658");
ПараметрыЗапроса.Вставить("to", "1125899906842673");
ПараметрыЗапроса.Вставить("weight", 12);
ПараметрыЗапроса.Вставить("width", 1);
ПараметрыЗапроса.Вставить("volume", 1);
ПараметрыЗапроса.Вставить("type", 1);
// Пример с параметром, который требует кодирования
ПараметрыЗапроса.Вставить("comment", "Тестовый запрос с пробелами");

// 2. Вызываем нашу функцию для формирования строки
СтрокаПараметров = СформироватьСтрокуПараметров(ПараметрыЗапроса);

// 3. Выполняем запрос
АдресСервера = "api.jde.ru";
АдресРесурса = "/vD/calculator/price?" + СтрокаПараметров;

Соединение = Новый HTTPСоединение(АдресСервера, , , , , , Новый ЗащищенноеСоединениеOpenSSL());
Запрос = Новый HTTPЗапрос(АдресРесурса);
Ответ = Соединение.Получить(Запрос);
// ...

Этот подход является наиболее сбалансированным решением для большинства задач.

Решение 3: Использование внешних библиотек (фреймворков)

Для проектов с большим количеством интеграций или сложным взаимодействием с API существуют готовые внешние библиотеки. Они инкапсулируют всю низкоуровневую работу с HTTP-запросами. Например, вы можете использовать универсальный модуль для быстрой организации HTTP-сервисов и API или применить готовый фреймворк для интеграции между системами 1С без боли, который значительно упрощает разработку.

Одной из таких библиотек является "КоннекторHTTP". С ее помощью код для выполнения запроса становится еще лаконичнее и полностью соответствует первоначальному желанию автора — передавать параметры в виде объекта.

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


// Создаем структуру с параметрами
ПараметрыСтруктура = Новый Структура;
ПараметрыСтруктура.Вставить("from", "1125899906842658");
ПараметрыСтруктура.Вставить("to", "1125899906842673");
ПараметрыСтруктура.Вставить("weight", "12");
ПараметрыСтруктура.Вставить("width", "8");
ПараметрыСтруктура.Вставить("volume", "1");
ПараметрыСтруктура.Вставить("type", "1");

// Выполняем GET-запрос, передавая URL и структуру параметров.
// Библиотека сама соберет URL, выполнит запрос и десериализует ответ из JSON.
Результат = КоннекторHTTP.GetJson("https://api.jde.ru/vD/calculator/price", ПараметрыСтруктура);

Преимущества: максимальная простота и читаемость кода, меньше рутинных операций, готовые механизмы для авторизации, обработки ошибок, работы с JSON/XML.

Недостатки: необходимость подключения и изучения стороннего кода (обработки, общего модуля) в конфигурацию.

Важное замечание: Тело запроса и метод GET

В ходе обсуждения возник вопрос, можно ли передать параметры через тело запроса с помощью метода УстановитьТелоИзСтроки() объекта HTTPЗапрос. Ответ — нет, для GET-запросов так делать не следует.

Согласно стандарту HTTP, метод GET предназначен для получения данных, и все необходимые для этого параметры должны передаваться исключительно через URL. Примеры правильного проектирования взаимодействия можно подсмотреть в подсистеме автоматического импорта задач из Jira через REST API, где параметры фильтрации передаются именно в строке запроса.

Хотя стандарт технически не запрещает наличие тела у GET-запроса, он также говорит, что сервер должен его игнорировать. Большинство веб-серверов и API-шлюзов так и поступают. Поэтому передача данных в теле GET-запроса является плохой практикой и почти гарантированно не будет работать.

Методы УстановитьТело...() предназначены для таких HTTP-методов, как POST, PUT, PATCH, которые предполагают отправку данных на сервер для создания или изменения ресурсов.

← На главную