В современной разработке на платформе 1С:Предприятие 8.3 интеграция с внешними сервисами через API стала повседневной задачей. Чаще всего обмен данными происходит с использованием протокола HTTP и формата JSON. В данной статье мы подробно разберем процесс взаимодействия с внешним сайтом: от отправки запроса до извлечения конкретных значений из сложных вложенных структур JSON для последующего заполнения реквизитов формы.
Прежде чем приступать к разбору данных, нам необходимо их получить. Для этого в 1С используются объекты HTTPСоединение и HTTPЗапрос. Разберем по шагам, как настроить безопасное соединение с сервером и отправить GET-запрос.
Проанализируем пример кода, который устанавливает связь с внешним ресурсом (в данном случае — API NASA):
// Указываем адрес сервера и параметры защищенного соединения
Сервер = "api.nasa.gov";
Порт = 443;
Защита = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(Сервер, Порт, , , , , Защита);
// Формируем запрос с указанием ресурса и параметров (API-ключа)
АдресРесурса = "/planetary/apod?api_key=DEMO_KEY&count=5";
Запрос = Новый HTTPЗапрос(АдресРесурса);
// Выполняем запрос и получаем ответ
РезультатЗапроса = Соединение.Получить(Запрос);
В этом фрагменте мы создаем объект защищенного соединения, что критически важно для работы по протоколу HTTPS. Метод Получить() отправляет запрос и возвращает объект HTTPОтвет, который содержит в себе тело ответа и служебную информацию (коды состояния).
После того как сервер вернул ответ, нам нужно преобразовать его из бинарных данных в обычную строку, с которой 1С сможет работать как с текстом. Для этого используется метод ПолучитьТелоКакСтроку(). Рекомендуется всегда явно указывать кодировку UTF-8, так как это стандарт для формата JSON.
Рассмотрим, как подготовить данные для парсинга:
Если РезультатЗапроса.КодСостояния = 200 Тогда
СтрокаJSON = РезультатЗапроса.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
// Инициализируем чтение JSON
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);
// Преобразуем JSON в объекты 1С (Структура или Массив)
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
Иначе
Сообщить("Ошибка при запросе: " + РезультатЗапроса.КодСостояния);
КонецЕсли;
Здесь важно отметить: функция ПрочитатьJSON() автоматически преобразует объекты JSON в Структуру 1С, а массивы JSON — в Массив 1С. Это значительно упрощает дальнейшую работу.
Часто новички сталкиваются с ситуацией, когда при попытке перебора полученных данных циклом Для каждого, программа сообщает, что значением является "Структура". Это означает, что JSON содержит вложенные объекты. Выясним причину: формат JSON иерархичен, и один ключ может содержать в себе не просто строку, а целый набор других ключей.
Если структура ответа выглядит, например, так:
{"data": {"items": [{"name": "Товар 1", "price": 100}], "meta": "ok"}}
То для получения названия товара нам нужно "прошагать" по всем уровням вложенности. Рассмотрим два способа обращения к данным.
Если мы заранее знаем структуру ответа, мы можем обращаться к элементам напрямую через имя ключа в квадратных скобках. Это самый быстрый и надежный способ.
// Допустим, переменная "Данные" уже содержит результат ПрочитатьJSON
// Нам нужно получить значение из узла data -> items[0] -> name
Если ТипЗнч(Данные) = Тип("Структура") И Данные.Свойство("data") Тогда
ВложенныеДанные = Данные["data"];
Если ВложенныеДанные.Свойство("items") Тогда
МассивТоваров = ВложенныеДанные["items"];
// Получаем первый элемент массива (индекс 0)
ПервыйТовар = МассивТоваров[0];
// Заполняем поле на форме
Объект.ИмяТовара = ПервыйТовар["name"];
Объект.Цена = ПервыйТовар["price"];
КонецЕсли;
КонецЕсли;
Если структура ответа динамическая или нам нужно найти определенный ключ среди множества других, мы используем рекурсивный обход или вложенные циклы. Проанализируем ситуацию, когда мы перебираем элементы "верхнего" уровня:
Для Каждого Элемент Из Данные Цикл
// Элемент.Ключ - имя свойства
// Элемент.Значение - само значение (может быть числом, строкой или новой структурой)
Если ТипЗнч(Элемент.Значение) = Тип("Структура") Тогда
// Мы нашли вложенный объект, нужно "зайти" внутрь
Для Каждого ВложенныйЭлемент Из Элемент.Значение Цикл
Сообщить("Ключ: " + ВложенныйЭлемент.Ключ + ", Значение: " + ВложенныйЭлемент.Значение);
КонецЦикла;
Иначе
Сообщить("Ключ: " + Элемент.Ключ + ", Значение: " + Элемент.Значение);
КонецЕсли;
КонецЦикла;
Чтобы ваша интеграция работала стабильно и не вызывала ошибок у пользователей, необходимо учитывать следующие моменты:
КодСостояния равен 200. Сервер может вернуть ошибку 404 (не найдено), 401 (ошибка авторизации) или 500 (внутренняя ошибка сервера), и в теле ответа будет не ожидаемый JSON, а текст ошибки или HTML-страница.Соединение.Получить() в конструкцию Попытка...Исключение. Если у пользователя пропадет интернет или сервер будет недоступен, программа завершится аварийно без этой обработки.Структура не могут содержать пробелы, начинаться с цифр или содержать дефисы. Если API возвращает ключи типа "item-id", функция ПрочитатьJSON может выдать ошибку или проигнорировать поле. В таких случаях используйте ИмяТипаПостроения.Соответствие в качестве второго параметра функции ПрочитатьJSON.Объект.Сумма = Число(ЗначениеИзJSON);.Сведем все знания воедино и напишем готовую процедуру, которая запрашивает данные и заполняет поле на форме 1С:
&НаСервере
Процедура ЗаполнитьДанныеИзAPIНаСервере()
НС = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение("api.example.com", 443, , , , , НС);
Запрос = Новый HTTPЗапрос("/v1/get_info?id=123");
Попытка
Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 200 Тогда
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
// Используем Соответствие для надежности
Результат = ПрочитатьJSON(Чтение, Ложь);
Чтение.Закрыть();
// Предположим, ответ: {"status": "success", "payload": {"target_value": "Привет, 1С!"}}
Если Результат.Получить("status") = "success" Тогда
ДанныеПэйлоад = Результат.Получить("payload");
Если ТипЗнч(ДанныеПэйлоад) = Тип("Соответствие") Тогда
Объект.ПолеНаФорме = ДанныеПэйлоад.Получить("target_value");
КонецЕсли;
КонецЕсли;
КонецЕсли;
Исключение
ОбщегоНазначения.СообщитьПользователю("Не удалось связаться с сервером: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
Мы проанализировали основные сложности, возникающие при работе с API, и выяснили, что ключ к успеху — в понимании иерархии объектов JSON. Используйте встроенные средства платформы ЧтениеJSON, внимательно следите за вложенностью структур и всегда проверяйте ответы сервера на корректность.