Рассмотрим частую проблему, с которой сталкиваются разработчики при интеграции с 1С через стандартный протокол OData. Допустим, мы получаем документ в формате JSON и видим, что для табличной части возвращаются только ссылки-идентификаторы (GUID), например, Номенклатура_Key. Нам же необходимо подтянуть строковое наименование, артикул и другие реквизиты связанных справочников. Попробуем разобраться, как правильно решить эту задачу.
В начале проанализируем типичный подход. Разработчик делает GET-запрос к документу, например, к документу реализации товаров:
// Создать HTTP-запрос на основе URL.
АдресРесурса = "/*******/odata/standard.odata/Document_РеализацияТоваров(guid'" + UID + "')?$format=json";
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса);
После получения ответа и его десериализации через ПрочитатьJSON, разработчик перебирает строки табличной части и обнаруживает, что вместо полноценных данных номенклатуры доступны только GUID:
ТоварыНакладной = Док.Получить("Товары");
Если ТоварыНакладной.Количество() > 0 Тогда
Для каждого Товар Из ТоварыНакладной Цикл
нСтр = Товары.Добавить();
// Здесь мы получаем только GUID, а нужно еще и наименование!
нСтр.Номенклатура = Товар.Получить("Номенклатура_Key");
нСтр.Характеристика = Товар.Получить("Характеристика_Key");
нСтр.Количество = Товар.Получить("Количество");
нСтр.Цена = Товар.Получить("Цена");
КонецЦикла;
КонецЕсли;
Логичным шагом кажется использование параметра $expand, который в OData предназначен для разворачивания связанных сущностей. Однако, стандартный REST-интерфейс 1С реализован на базе старого протокола OData версии 3. Согласно официальной документации 1С, на $expand наложены жесткие ограничения:
Разберем самую опасную идею — делать отдельный OData-запрос для каждой строки табличной части. Если в документе 200 строк, скрипт отправит 200 GET-запросов к серверу 1С. Это классический антипаттерн «N+1 запрос».
Каждый HTTP-вызов к OData — это затраты времени на установку сетевого соединения, авторизацию, проверку прав, парсинг запроса веб-сервером и платформой. Если несколько пользователей одновременно откроют такие документы, мы получим тысячи запросов в секунду. Это гарантированно исчерпает пул сеансов платформы и «повесит» веб-сервер (IIS или Apache).
Посмотрим на более жизнеспособный обходной путь. Мы можем собрать все уникальные GUID номенклатуры из полученной табличной части в один массив и отправить один дополнительный запрос к справочнику.
Поскольку 1С поддерживает только OData v3, удобный оператор IN (появившийся в OData v4) здесь не сработает. Нам придется реализовывать отбор списка через логическое сложение оператором OR. Фильтр будет выглядеть так:
$filter=Ref_Key eq guid'...' or Ref_Key eq guid'...' or Ref_Key eq guid'...'
Важные нюансы реализации этого подхода:
OR сотни GUID, сервер вернет ошибку 414 URI Too Long.Catalog_Номенклатура пакетами.Рассмотрим самое правильное и архитектурно верное решение. Если стандартный интерфейс OData требует написания сложных "костылей" с чанками и склейкой данных на клиенте, от него лучше отказаться. Гораздо эффективнее разработать собственный HTTP-сервис прямо в конфигурации 1С (или в расширении).
Разберем по шагам, как это реализовать:
HTTPСервис (например, с корневым URL myapi)./v1/documents/realization/{id} и добавляем метод для HTTP-глагола GET.ЗаписьJSON и возвращаем ответ.Пример логики запроса внутри HTTP-сервиса:
ТекстЗапроса =
"ВЫБРАТЬ
| РеализацияТоваровУслугТовары.Номенклатура.УникальныйИдентификатор() КАК Номенклатура_Key,
| РеализацияТоваровУслугТовары.Номенклатура.Наименование КАК Номенклатура_Desc,
| РеализацияТоваровУслугТовары.Количество КАК Количество,
| РеализацияТоваровУслугТовары.Цена КАК Цена
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
|ГДЕ
| РеализацияТоваровУслугТовары.Ссылка = &СсылкаНаДокумент";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("СсылкаНаДокумент", ИскомаяСсылка);
Результат = Запрос.Выполнить().Выгрузить();
// Далее формируем массив структур и записываем в JSON
Преимущества такого подхода:
В заключение, если вам нужно получать сложные, вложенные структуры данных с развернутыми реквизитами из 1С, всегда делайте выбор в пользу разработки собственных HTTP-сервисов, оставляя стандартный интерфейс OData для простых задач (выгрузки плоских списков и CRUD-операций одиночных справочников).