Как в 1С правильно сформировать вложенную JSON-структуру (ассоциативный массив) для отправки в HTTP-запросе?

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

При интеграции 1С со сторонними веб-сервисами, особенно написанными на PHP, Python или JavaScript, разработчики часто сталкиваются с путаницей в терминологии типов данных. Одной из распространенных проблем является формирование правильной структуры JSON для полезной нагрузки (payload) при отправке запросов, например, при генерации JWT-токенов.

В этой статье мы подробно разберем ситуацию, когда сторонний сервер ожидает получить «двухуровневый массив» или ассоциативный массив, а 1С при стандартной сериализации выдает некорректный формат. Мы выясним, почему возникает ошибка, разберем различия в типах данных между 1С и JSON, и научимся правильно формировать вложенные объекты.

Суть проблемы: Массив или Структура?

Рассмотрим типичную задачу. Нам необходимо отправить POST-запрос на сервер, передав JWT-токен. В полезной нагрузке этого токена должен содержаться параметр cnt, внутри которого находятся данные, например, ИНН. Сторонние разработчики (часто пишущие на PHP) могут сформулировать требование как необходимость передать «двухуровневый массив»:


[cnt] => Array ( 
    [inn] => 123456789 
)

Если попытаться реализовать это в 1С буквально, используя тип данных Массив, и затем сериализовать это в JSON, мы получим следующий результат:


// Неверный результат сериализации массива 1С
"cnt": [
    {
        "inn": "123456789"
    }
]

Обратите внимание на квадратные скобки []. В синтаксисе JSON они обозначают список (массив). Сервер, получая такой пакет, не может обратиться к полю по имени ключа напрямую (например, payload.cnt.inn), так как cnt является списком, и ему нужно обращаться по индексу (например, payload.cnt[0].inn). В результате сервер возвращает ошибку валидации данных, например: "The INN is bad".

Теоретическая часть: Сопоставление типов 1С и JSON

Чтобы решить проблему, нужно понимать, как механизмы сериализации (например, объект ЗаписьJSON) преобразуют типы 1С в формат JSON. Давайте проанализируем основные соответствия:

  1. Массив (1С) = JSON Array (Список)

    В 1С это коллекция индексированных значений. В JSON это значения в квадратных скобках [...]. Используется, когда порядок элементов важен, а ключи (имена) элементов не нужны.

  2. Структура (1С) = JSON Object (Объект)

    В 1С это коллекция пар "Ключ-Значение", где ключ — строка. В JSON это значения в фигурных скобках {...}. Это аналог "Ассоциативного массива" в PHP или "Словаря" (Dictionary) в других языках. Именно этот тип нужен, когда сторонний API требует передачу параметров по именам.

  3. Соответствие (1С) = JSON Object (Объект)

    Также преобразуется в объект {}, если ключами являются строки. Однако порядок полей при сериализации Соответствия не всегда гарантирован (хотя в стандарте JSON порядок ключей в объекте и не должен иметь значения, некоторые парсеры могут быть к этому чувствительны).

Важное замечание про PHP: В языке PHP термин "Array" (массив) используется и для обычных списков ['a', 'b'], и для ассоциативных массивов ['key' => 'value']. Поэтому, когда PHP-разработчик просит отправить "массив", он часто имеет в виду JSON-объект (Structure в терминах 1С).

Решение задачи: Создание вложенной структуры

Теперь, когда мы выяснили разницу, перейдем к правильной реализации. Нам нужно получить JSON следующего вида:


{
    "cnt": {
        "inn": "123456789"
    }
}

Здесь мы видим вложенность: объект внутри объекта (фигурные скобки внутри фигурных скобок). В терминах 1С это означает, что нам нужно создать одну Структуру и поместить ее как значение внутрь другой Структуры.

Давайте рассмотрим пошаговый алгоритм написания кода в 1С.

Шаг 1. Формирование вложенного объекта

Сначала создадим ту часть данных, которая находится на самом глубоком уровне вложенности. В нашем случае это данные с ИНН.


// Создаем структуру для внутренних данных
ДанныеИНН = Новый Структура;
ДанныеИНН.Вставить("inn", "123456789");

Шаг 2. Формирование основного объекта (Payload)

Теперь создадим корневую структуру и поместим в неё наши ДанныеИНН под ключом cnt.


// Создаем корневую структуру
Payload = Новый Структура;
// Вставляем структуру в структуру
Payload.Вставить("cnt", ДанныеИНН); 

// Добавим другие обязательные поля токена, если нужно
Payload.Вставить("iat", ТекущаяУниверсальнаяДатаВМиллисекундах());
// ... и так далее

Шаг 3. Сериализация в JSON

Для преобразования полученной структуры 1С в строку JSON используем объект ЗаписьJSON. Это наиболее надежный способ, который гарантирует правильную расстановку скобок и кавычек.


ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();

// Записываем нашу структуру
ЗаписатьJSON(ЗаписьJSON, Payload);

// Получаем готовую строку
СтрокаJSON = ЗаписьJSON.Закрыть();

В результате переменная СтрокаJSON будет содержать именно то, что ожидает сервер:

{"cnt":{"inn":"123456789"},"iat":...}

Разбор ошибок: Почему не работал Массив?

Давайте проанализируем ошибку, которую допускал автор вопроса изначально. Код выглядел примерно так:


// ОШИБОЧНЫЙ ВАРИАНТ
ВложенныйМассив = Новый Массив;
СтруктураСИнн = Новый Структура("inn", "123456789");
ВложенныйМассив.Добавить(СтруктураСИнн);

Payload = Новый Структура;
Payload.Вставить("cnt", ВложенныйМассив);

При сериализации такого кода 1С видит тип Массив и честно оборачивает его в квадратные скобки []. Получается JSON:

{"cnt": [{"inn": "123456789"}]}

Сервер на PHP, получая такой запрос, пытается выполнить код вроде $data['cnt']['inn']. Но так как cnt теперь массив (список), у него нет ключа inn, у него есть только индекс 0. Ключ inn находится внутри элемента с индексом 0. Поэтому проверка на сервере падает с ошибкой, утверждая, что ИНН не найден или некорректен.

Дополнительные рекомендации

При работе с JSON в 1С стоит учитывать еще несколько важных моментов, чтобы избежать подобных проблем в будущем:

  1. Проверяйте "сырой" JSON. Если сервер возвращает ошибку, не полагайтесь только на визуализацию данных в отладчике 1С, используйте средства для просмотра JSON с форматированием. Скопируйте итоговую строку JSON (результат метода ЗаписьJSON.Закрыть()) и проверьте её в любом онлайн-валидаторе JSON. Обращайте внимание на типы скобок: {} — это объект, [] — это массив.
  2. Используйте Структуры для именованных полей. Если в документации API вы видите фигурные скобки { "key": "value" }, в 1С всегда используйте Структура. Для отладки и эмуляции запросов удобно применять аналог Postman на платформе 1С.
  3. Используйте Массивы для списков. Если в документации API вы видите квадратные скобки [ "value1", "value2" ], в 1С используйте Массив.
  4. Осторожнее с XDTO. Иногда для сериализации используют СериализаторXDTO. Он мощнее, но по умолчанию может добавлять в JSON служебные поля (например, #type), специфичные для платформы 1С. Сторонние системы их не поймут. Если используете XDTO, убедитесь, что настройки сериализации отключены для вывода информации о типах, либо используйте "чистую" запись через ЗаписьJSON.

Таким образом, для решения задачи "двухуровневого ассоциативного массива" (в терминологии PHP) в 1С необходимо использовать вложенные структуры. Это обеспечит корректную генерацию JSON-объектов и успешную валидацию данных на принимающей стороне.

← На главную