При интеграции 1С с внешними системами через API одной из самых частых задач становится формирование сложных JSON-пакетов с вложенными структурами. На первый взгляд задача кажется тривиальной: собрать данные в Соответствие или Структуру (например, используя Swagger) и вызвать метод ЗаписатьJSON. Однако на практике разработчики часто сталкиваются с ошибками на этапе записи, когда во вложенных объектах оказываются типы данных, специфичные для 1С, но «непонятные» формату JSON.
В этой статье мы подробно разберем, как правильно формировать вложенные объекты, почему возникают ошибки при сериализации и как автоматизировать процесс преобразования типов (используя конструктор API), чтобы ваш код был надежным и универсальным.
Проанализируем типичную ситуацию (в этом поможет Python-коннектор к 1С). Допустим, нам нужно передать данные о номенклатуре, где поле «бренд» является отдельным объектом со своими свойствами (uid и name). Рассмотрим пример кода, который может вызвать затруднения:
ДанныеНоменклатуры = Новый Соответствие;
ДанныеНоменклатуры.Вставить("country", СсылкаНаОбъект.Производитель.Наименование);
// Пытаемся вставить вложенный объект
ДанныеНоменклатуры.Вставить("brand", СформироватьДанныеДляЗапросаПоБренду(СсылкаНаОбъект));
Функция СформироватьДанныеДляЗапросаПоБренду(СсылкаНаОбъект)
ДанныеБренда = Новый Соответствие;
// ОШИБКА ЗДЕСЬ: Прямая вставка уникального идентификатора
ДанныеБренда.Вставить("uid", СсылкаНаОбъект.Марка.УникальныйИдентификатор());
ДанныеБренда.Вставить("name", СсылкаНаОбъект.Марка.Наименование);
Возврат ДанныеБренда;
КонецФункции
При попытке выполнить ЗаписатьJSON(ЗаписьJSON, ДанныеНоменклатуры) система выдаст ошибку. Проблема заключается в том, что стандартный метод платформы умеет работать только с ограниченным набором типов: Строка, Число, Булево, Дата, Массив, Структура и Соответствие. Тип УникальныйИдентификатор или любая Ссылка не входят в этот список и должны быть предварительно преобразованы.
Самый быстрый способ решить проблему — привести все сложные значения к строковому виду (вот пример преобразования данных) непосредственно перед помещением в коллекцию. Рассмотрим подробнее, как изменить функцию формирования данных бренда, чтобы она стала валидной для JSON.
Вместо передачи объекта типа УникальныйИдентификатор, мы используем функцию Строка() или специализированную функцию XMLСтрока(). Последняя особенно полезна, так как она корректно работает со всеми ссылочными типами данных 1С.
Функция СформироватьДанныеДляЗапросаПоБренду(СсылкаНаОбъект)
ДанныеБренда = Новый Соответствие;
// Преобразуем идентификатор в строку явным образом
ДанныеБренда.Вставить("uid", XMLСтрока(СсылкаНаОбъект.Марка));
ДанныеБренда.Вставить("name", СсылкаНаОбъект.Марка.Наименование);
Возврат ДанныеБренда;
КонецФункции
Теперь, когда во вложенном Соответствии содержатся только примитивные типы, метод ЗаписатьJSON отработает без ошибок, и мы получим корректную структуру объекта внутри JSON.
Если вложенных объектов много, ручное преобразование каждого поля через Строка() становится трудоемким и засоряет код. Начиная с версии 8.3.6, платформа предлагает элегантное решение — параметр ФункцияОбратногоВызова в методе ЗаписатьJSON.
Разберем по шагам, как это работает. Если сериализатор встречает тип данных, который он не может обработать самостоятельно (например, перечисление или ссылку), он обращается к вашей функции. Мы можем написать универсальный обработчик:
// Основной код выгрузки
НастройкиСериализации = Новый НастройкиСериализацииJSON;
НастройкиСериализации.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.ISO8601;
ЗаписатьJSON(ЗаписьJSON, ДанныеДляЗапроса, НастройкиСериализации, "МояФункцияПреобразования");
// Функция-обработчик «проблемных» типов
Функция МояФункцияПреобразования(Свойство, Значение, ДополнительныеПараметры, Отказ) Экспорт
ТипЗначения = ТипЗнч(Значение);
// Если это ссылка или идентификатор — превращаем в строку
Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗначения)
Или ТипЗначения = Тип("УникальныйИдентификатор") Тогда
Возврат XMLСтрока(Значение);
ИначеЕсли Перечисления.ТипВсеСсылки().СодержитТип(ТипЗначения) Тогда
Возврат Строка(Значение); // Или имя значения перечисления
КонецЕсли;
// Если мы не знаем, что делать, флаг Отказ оставит стандартную обработку (вызовет ошибку)
Возврат Значение;
КонецФункции
Использование обработчика позволяет нам собирать вложенные Соответствия, не задумываясь о типах внутри. Платформа сама «позовет» нашу функцию, когда дойдет до вложенного объекта brand и его поля uid.
При формировании вложенных объектов важно правильно выбрать тип коллекции. Часто программисты используют Структуру, но у нее есть два существенных ограничения для JSON:
@id или brand-name, Структура не подойдет.Структуре при выгрузке.В то же время Соответствие позволяет использовать любые строки в качестве ключей. Поэтому для формирования вложенных объектов, предназначенных для интеграции, рекомендуется использовать именно Соответствие.
Дата — еще один тип, который часто вызывает вопросы при вложении объектов. По умолчанию 1С может выгружать дату в специфическом формате. Чтобы вложенные объекты содержали даты в стандарте ISO 8601 (принятом в большинстве веб-сервисов), необходимо использовать объект НастройкиСериализацииJSON.
Настройки = Новый НастройкиСериализацииJSON;
Настройки.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.ISO8601;
// Теперь во всех вложенных структурах даты будут вида "2023-10-25T12:00:00"
ЗаписатьJSON(ЗаписьJSON, СформированныеДанные, Настройки);
Иногда в контексте JSON упоминается СериализаторXDTO. Это мощный инструмент, который может выгрузить объект 1С (например, весь справочник) одной командой. Однако помните: СериализаторXDTO часто добавляет много лишней технической информации (типы данных, пространства имен), что может быть неприемлемо для простых REST API. Для передачи конкретных полей во вложенных объектах лучше использовать ручную сборку через Соответствие и метод ЗаписатьJSON, как мы рассмотрели выше.
Подводя итог, проанализируем основные правила успешной выгрузки вложенных объектов:
Ссылка и УникальныйИдентификатор должны быть преобразованы в строку через XMLСтрока().Соответствие вместо Структуры для ключей, содержащих спецсимволы.ЗаписьJSON, чтобы платформа автоматически обработала экранирование кавычек и спецсимволов в строковых данных ваших брендов и номенклатур.Следуя этим правилам, вы сможете формировать вложенные объекты любой сложности, обеспечивая корректную передачу данных между 1С и внешними информационными системами.