При разработке веб-сервисов в среде 1С:Предприятие одной из наиболее частых задач является передача информации об объектах (документах, справочниках) из одной информационной базы в другую. Часто возникает ситуация, когда недостаточно просто передать номер и дату документа; для последующего изменения объекта (например, редактирования комментария) необходимо иметь возможность однозначно идентифицировать его в базе-источнике. Лучшим способом для этого является передача уникального идентификатора (GUID) или ссылки.
В этой статье мы подробно разберем, как организовать передачу ссылок через XDTO, как обойти ограничение языка запросов по получению УИД и какие современные механизмы платформы упрощают эту задачу. Мы проанализируем различные подходы — от классической сериализации до использования системы компоновки данных.
Рассмотрим стандартную ситуацию: нам нужно получить список документов с определенными реквизитами и их уникальными идентификаторами для передачи через веб-сервис. Основная сложность заключается в том, что язык запросов 1С не умеет напрямую возвращать УникальныйИдентификатор() объекта. Программистам часто приходится прибегать к обходу результата запроса в цикле:
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
УИД_Строкой = Строка(Выборка.Ссылка.УникальныйИдентификатор());
// Добавление в таблицу или структуру
КонецЦикла;
Такой подход крайне неэффективен на больших объемах данных, так как обращение через точку к Ссылка.УникальныйИдентификатор() заставляет платформу выполнять дополнительные действия. Давайте разберем более быстрые способы решения этой задачи.
Это один из самых изящных способов получить строковое представление идентификаторов без медленных циклов. Система компоновки данных работает на более низком уровне и позволяет вычислять значения быстрее. Проанализируем алгоритм действий:
Ссылка.ИдентификаторСтрокой и пропишем выражение: Строка(Ссылка.УникальныйИдентификатор()).Посмотрим на пример программной реализации этого метода:
Схема = Новый СхемаКомпоновкиДанных;
// Описание источника данных, набора данных и запроса...
// Добавление вычисляемого поля
ПолеУИД = Схема.ВычисляемыеПоля.Добавить();
ПолеУИД.ПутьКДанным = "Идентификатор";
ПолеУИД.Выражение = "Строка(Ссылка.УникальныйИдентификатор())";
// Настройка компоновки и вывод в таблицу значений
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Схема.НастройкиПоУмолчанию);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТаблицуЗначений;
ТаблицаРезультат = ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Этот метод значительно сокращает время подготовки данных для веб-сервиса, особенно если нужно передать сотни или тысячи строк.
Если ваша задача — быстро передать ссылку, которую потом можно легко превратить обратно в объект в той же базе, воспользуемся механизмом навигационных ссылок. Навигационная ссылка — это строка формата e1cib/data/Документ.РеализацияТоваровУслуг?ref=..., которая уже содержит в себе и тип объекта, и его GUID.
Разберем преимущества этого подхода:
Пример получения ссылки для отправки:
ТекстСсылки = ПолучитьНавигационнуюСсылку(ДокументСсылка);
// Передаем ТекстСсылки как параметр веб-сервиса
Пример восстановления объекта на стороне веб-сервиса:
СсылкаНаОбъект = ПолучитьСсылкуПоНавигационнойСсылке(ПереданнаяСтрока);
Если СсылкаНаОбъект = Неопределено Тогда
// Обработка ошибки
КонецЕсли;
ДокументОбъект = СсылкаНаОбъект.ПолучитьОбъект();
Для более "архитектурно правильного" решения (например, если планируется интеграция не только с 1С, но и со сторонними системами) стоит описать ссылку в самом XDTO-пакете. Рассмотрим структуру, которую рекомендует использовать библиотека интеграции с 1С:Документооборотом.
Создадим тип объекта в XDTO-пакете (например, с именем ObjectID), который будет содержать два свойства:
ID (тип string) — здесь будем хранить GUID.Type (тип string) — здесь будем хранить имя метаданных (например, "Документ.РеализацияТоваровУслуг").Проанализируем процесс сериализации. При использовании СериализаторXDTO можно автоматически записывать ссылки, если типы объектов в базах совпадают. Однако, если мы работаем с произвольными данными, лучше заполнять структуру вручную:
ТипОбъектаXDTO = ФабрикаXDTO.Тип("http://www.my-service.ru", "ObjectID");
ОбъектИдентификатор = ФабрикаXDTO.Создать(ТипОбъектаXDTO);
ОбъектИдентификатор.ID = Строка(ДокументСсылка.УникальныйИдентификатор());
ОбъектИдентификатор.Type = ДокументСсылка.Метаданные().ПолноеИмя();
На стороне приемника (в веб-сервисе) мы восстанавливаем ссылку следующим образом:
ИмяМетаданных = ОбъектИдентификаторXDTO.Type;
Гуид = Новый УникальныйИдентификатор(ОбъектИдентификаторXDTO.ID);
Ссылка = Документы[Сред(ИмяМетаданных, 10)].ПолучитьСсылку(Гуид);
// Теперь у нас есть живая ссылка для поиска и редактирования документа
Выясним, всегда ли нужно писать собственный веб-сервис. Если задача сводится к тому, чтобы "видеть список и редактировать пару полей", 1С предоставляет мощный встроенный механизм — OData.
При включении стандартного интерфейса OData:
Ref_Key (это и есть GUID).PATCH запрос, содержащий только измененное поле.Это избавляет от необходимости описывать XDTO-пакеты и писать программный код веб-сервиса вручную. Все ссылки и типы данных платформа берет на себя.
Мы рассмотрели несколько подходов к решению задачи. Выбор конкретного метода зависит от ваших требований:
Помните, что передача ссылки — это только половина дела. При получении ссылки обратно в веб-сервисе всегда проверяйте её на "битость" (существование объекта в базе) перед тем, как выполнять метод ПолучитьОбъект(), чтобы избежать аварийного завершения работы сервиса.