При работе с внешними API часто возникает задача выполнить GET-запрос с набором динамических параметров. В 1С для этого используются объекты HTTPСоединение и HTTPЗапрос. Для новичков, желающих закрепить базовые навыки, существует интерактивный обучающий курс по работе с HTTP-запросами, где подробно разбираются GET, POST и другие методы. Однако, в отличие от формирования тел запросов в формате JSON или XML, стандартные средства платформы не предоставляют прямого способа передать параметры GET-запроса в виде структуры или соответствия. Требуется самостоятельно сформировать строку URL с параметрами.
Рассмотрим, как это сделать правильно и какие подходы существуют для упрощения этой задачи, чтобы не "изобретать велосипед" в каждом новом запросе — для этого подойдёт обработка для логирования и анализа HTTP-запросов.
Самый прямой и очевидный способ — это собрать строку 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Запрос(АдресРесурса);
Попытка
Ответ = Соединение.Получить(Запрос);
КодСостояния = Ответ.КодСостояния;
// Дальнейшая обработка ответа...
Исключение
ОписаниеОшибки = ОписаниеОшибки();
// Обработка исключения...
КонецПопытки;
Преимущества: простота и наглядность для фиксированных запросов.
Недостатки: неудобно при большом количестве динамических параметров, легко допустить ошибку при конкатенации строк, код становится громоздким.
Чтобы сделать код более читаемым, гибким и универсальным, лучшей практикой является создание собственной вспомогательной функции. Эта функция будет принимать на вход структуру или соответствие с параметрами и возвращать готовую для использования строку. Такой подход важен, если вы строите надежную систему интеграции 1С с внешними сервисами, такими как Google Таблицы, где параметры запроса могут быть многочисленными и сложными.
Ключевой момент, который необходимо учесть, — это кодирование значений параметров. Если значение параметра может содержать пробелы, кириллические символы или спецсимволы (&, =, ?, /), их необходимо преобразовать в безопасный для URL формат с помощью функции URLЗакодировать(). В противном случае сервер может неверно интерпретировать запрос.
Разберем по шагам создание такой функции:
&.Посмотрим на пример реализации такой функции:
&НаСервереБезКонтекста
Функция СформироватьСтрокуПараметров(СтруктураПараметров)
Если СтруктураПараметров = Неопределено Или СтруктураПараметров.Количество() = 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Запрос(АдресРесурса);
Ответ = Соединение.Получить(Запрос);
// ...
Этот подход является наиболее сбалансированным решением для большинства задач.
Для проектов с большим количеством интеграций или сложным взаимодействием с 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.
Недостатки: необходимость подключения и изучения стороннего кода (обработки, общего модуля) в конфигурацию.
В ходе обсуждения возник вопрос, можно ли передать параметры через тело запроса с помощью метода УстановитьТелоИзСтроки() объекта HTTPЗапрос. Ответ — нет, для GET-запросов так делать не следует.
Согласно стандарту HTTP, метод GET предназначен для получения данных, и все необходимые для этого параметры должны передаваться исключительно через URL. Примеры правильного проектирования взаимодействия можно подсмотреть в подсистеме автоматического импорта задач из Jira через REST API, где параметры фильтрации передаются именно в строке запроса.
Хотя стандарт технически не запрещает наличие тела у GET-запроса, он также говорит, что сервер должен его игнорировать. Большинство веб-серверов и API-шлюзов так и поступают. Поэтому передача данных в теле GET-запроса является плохой практикой и почти гарантированно не будет работать.
Методы УстановитьТело...() предназначены для таких HTTP-методов, как POST, PUT, PATCH, которые предполагают отправку данных на сервер для создания или изменения ресурсов.