Интеграция 1С с внешними интернет-сервисами, сайтами и REST API чаще всего строится на обмене данными в формате JSON посредством HTTP-запросов. Разберем по шагам, как правильно подготовить данные в 1С, сериализовать их в JSON и выполнить отправку на удаленный сервер.
Процесс отправки информации состоит из двух ключевых этапов:
HTTPСоединение, подготовка HTTPЗапрос и отправка полезной нагрузки методом GET или POST с последующим анализом ответа.Начиная с версии платформы 8.3.6, в 1С появились встроенные объекты для прямой сериализации коллекций. Это исключает необходимость вручную конкатенировать строки и экранировать специальные символы.
Рассмотрим пример формирования вложенной структуры данных, соответствующей требованиям API (массив начислений по объектам):
// 1. Формируем структуру данных в памяти
МассивОбъектов = Новый Массив;
СтруктураКвартиры = Новый Структура;
СтруктураКвартиры.Вставить("apartment_number", "1");
СтруктураКвартиры.Вставить("month", "2016-11-00");
СтруктураКвартиры.Вставить("object_type", "квартира");
СтруктураКвартиры.Вставить("room_number", "");
СтруктураКвартиры.Вставить("accrual", 117.0);
СтруктураКвартиры.Вставить("total_debt", 231.0);
МассивОбъектов.Добавить(СтруктураКвартиры);
СтруктураТСЖ = Новый Структура;
СтруктураТСЖ.Вставить("tsg_id", 1);
СтруктураТСЖ.Вставить("objects", МассивОбъектов);
КореньДанных = Новый Массив;
КореньДанных.Добавить(СтруктураТСЖ);
// 2. Сериализуем данные в строку JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, КореньДанных);
СтрокаJSON = ЗаписьJSON.Закрыть();
Теперь рассмотрим отправку полученного JSON на сервер методом POST (что является стандартом для передачи массивов данных и начислений):
Сервер = "zzz.ru";
Ресурс = "/api/set/accruals/";
// Для HTTPS-соединений обязательно указываем ЗащищенноеСоединениеOpenSSL
Защита = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(Сервер, 443, , , , 30, Защита);
Запрос = Новый HTTPЗапрос(Ресурс);
Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
// Отключаем маркер последовательности байтов (BOM), чтобы не нарушать работу парсеров
Запрос.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Попытка
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если Ответ.КодСостояния = 200 ИЛИ Ответ.КодСостояния = 201 Тогда
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
// Обрабатываем успешный ответ сервера
Иначе
// Обработка ошибки сервера
КонецЕсли;
Исключение
// Обработка сетевой ошибки или недоступности хоста
ВызватьИсключение;
КонецПопытки;
Если спецификация стороннего сервиса жестко требует передачи JSON в параметрах строки запроса (как в строке https://zzz.ru/api/set/accruals/?login=...&ccc=[{...}]), необходимо помнить о нескольких критических ограничениях:
КодироватьСтроку, иначе веб-сервер вернет ошибку 400 (Bad Request).414 URI Too Long. В таких случаях выгрузку необходимо переводить на метод POST либо разбивать массив на небольшие порции.Пример формирования GET-запроса с закодированным параметром:
ПараметрJSON = КодироватьСтроку(СтрокаJSON, СпособКодированияСтроки.КодировкаURL);
Ресурс = СтрШаблон("/api/set/accruals/?login=%1&password=%2&ccc=%3",
КодироватьСтроку("ttt", СпособКодированияСтроки.КодировкаURL),
КодироватьСтроку("qqq123", СпособКодированияСтроки.КодировкаURL),
ПараметрJSON
);
Запрос = Новый HTTPЗапрос(Ресурс);
Ответ = Соединение.Получить(Запрос);
После отправки данных веб-сервер возвращает результат, который также может быть в формате JSON. Для его десериализации в объекты 1С используем функцию ПрочитатьJSON:
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8));
// Преобразуем JSON в Соответствие или Структуру
Результат = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Если ТипЗнч(Результат) = Тип("Структура") ИЛИ ТипЗнч(Результат) = Тип("Соответствие") Тогда
// Доступ к полям ответа
КонецЕсли;
Если выгрузка выполняется на платформе ниже 8.3.6 или требуется специфическая ручная сборка текстового представления, можно использовать универсальную функцию рекурсивного обхода коллекций:
&НаСервере
Функция СформироватьСтрокуJSON(Объект) Экспорт
СтрокаJSON = "";
Если ТипЗнч(Объект) = Тип("Массив") Тогда
СтрокаJSON = "[";
Для каждого Элемент Из Объект Цикл
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент) + ",";
КонецЦикла;
Если Прав(СтрокаJSON, 1) = "," Тогда
СтрокаJSON = Лев(СтрокаJSON, СтрДлина(СтрокаJSON) - 1);
КонецЕсли;
Возврат СтрокаJSON + "]";
ИначеЕсли ТипЗнч(Объект) = Тип("Структура") ИЛИ ТипЗнч(Объект) = Тип("Соответствие") Тогда
СтрокаJSON = "{";
Для каждого Элемент Из Объект Цикл
Если Элемент.Значение = "" Тогда
Продолжить;
КонецЕсли;
СтрокаJSON = СтрокаJSON + """" + Элемент.Ключ + """" + ":";
Если ТипЗнч(Элемент.Значение) = Тип("Строка") Тогда
СтрокаJSON = СтрокаJSON + """" + Элемент.Значение + """";
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Число") Тогда
СтрокаJSON = СтрокаJSON + СтрЗаменить(Строка(Элемент.Значение), Символы.НПП, "");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Булево") Тогда
СтрокаJSON = СтрокаJSON + Формат(Элемент.Значение, "БЛ=false; БИ=true");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Массив") ИЛИ ТипЗнч(Элемент.Значение) = Тип("Структура") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
Иначе
СтрокаJSON = СтрокаJSON + """" + Строка(Элемент.Значение) + """";
КонецЕсли;
СтрокаJSON = СтрокаJSON + ",";
КонецЦикла;
Если Прав(СтрокаJSON, 1) = "," Тогда
СтрокаJSON = Лев(СтрокаJSON, СтрДлина(СтрокаJSON) - 1);
КонецЕсли;
Возврат СтрокаJSON + "}";
КонецЕсли;
Возврат СтрокаJSON;
КонецФункции
Для обеспечения стабильной работы обмена на практике рекомендуем учитывать следующие правила:
Authorization: Bearer <token>) или протокол HTTPS.HTTPСоединение всегда задавайте параметр таймаута (например, 30 или 60 секунд), чтобы фоновые задания не зависали при сетевых сбоях.