При интеграции 1С со сторонними системами (например, клиентскими приложениями на Java) через веб-сервисы (SOAP/WSDL), разработчики часто сталкиваются с проблемой огромного размера WSDL-файла. Разберем типичную ситуацию: в XDTO-пакете для передачи кастомной модели данных используется ссылка на перечисление из стандартного пространства имен http://v8.1c.ru/8.1/data/enterprise/current-config. В результате при генерации WSDL клиентское приложение получает описание тысяч внутренних типов данных 1С, включая вложенные пакеты core и enterprise. Проанализируем, почему это происходит и как правильно организовать передачу данных, чтобы стороннее приложение получало только нужные DTO-объекты.
Рассмотрим подробнее назначение системных пакетов XDTO в платформе 1С. Пакет current-config — это, как следует из его названия, полное описание всех типов метаданных текущей конфигурации. Пакеты core и enterprise содержат базовые типы платформы. Если вы работаете с крупной конфигурацией (например, ERP), количество типов в этих пакетах исчисляется тысячами.
Использование current-config в веб-сервисах оправдано только в специфических случаях:
Для интеграции со сторонними системами передача объектов платформы напрямую — это антипаттерн. Если ссылаться на типы конфигурации, система автоматической сериализации действительно может преобразовать объект 1С в XML одной строкой, но ценой экспорта всей схемы базы данных наружу. Стороннему клиенту эти тысячи моделей данных не нужны и лишь усложняют генерацию классов на их стороне.
Выясним, как грамотно спроектировать обмен. Золотое правило интеграции: необходимо создавать собственный пакет XDTO, описывая в нем только те структуры (DTO-классы), которые действительно нужно отдать сторонней системе. В этот пакет нельзя добавлять типы данных из дерева конфигурации.
Создадим свои типы непосредственно в пакете XDTO. Важно, чтобы они опирались только на простые примитивные типы (такие как string, int, boolean) из стандартного пространства имен http://www.w3.org/2001/XMLSchema. Никаких ссылок на current-config быть не должно.
При таком подходе сериализацию объектов базы данных в структуры XDTO придется выполнять вручную программным кодом внутри обработчика метода веб-сервиса. Посмотрим на пример реализации такого обработчика:
// Получаем данные из базы 1С
Результат = СписокЗаказовПокупателей(ДатаНачала, ДатаОкончания, Параметры, Ошибка, ТекстОшибки);
// Инициализируем типы из нашего кастомного независимого пакета
XDTO_TypeOrder = ФабрикаXDTO.Тип(XDTO_URI, "Order");
XDTO_TypeOrderList = ФабрикаXDTO.Тип(XDTO_URI, "OrderList");
// Создаем корневой объект списка
OrderListXDTO = ФабрикаXDTO.Создать(XDTO_TypeOrderList);
// В цикле "накачиваем" XDTO данными из результата запроса/функции
Для каждого элРезультат Из Результат Цикл
OrderXDTO = ФабрикаXDTO.Создать(XDTO_TypeOrder);
// Заполняем простые поля (строки, числа, даты)
OrderXDTO.number = элРезультат.Номер;
OrderXDTO.date = элРезультат.Дата;
OrderXDTO.customer = элРезультат.Контрагент;
OrderXDTO.summa = элРезультат.Сумма;
OrderXDTO.organization = элРезультат.Организация;
OrderXDTO.manager = элРезультат.Ответственный;
OrderXDTO.department = элРезультат.Подразделение;
OrderXDTO.comment = элРезультат.Комментарий;
// Добавляем заполненный объект в список
OrderListXDTO.Order.Добавить(OrderXDTO);
КонецЦикла;
Теперь разберем самый интересный нюанс — передачу перечислений (Enums). В 1С значение типа ПеречислениеСсылка можно легко преобразовать в строковый идентификатор с помощью функции XMLСтрока(). Но если мы просто определим в нашем XDTO пакете поле с типом string, то клиентское приложение (например, на Java) тоже сгенерирует это поле как обычную строку (String).
Проблема такого подхода в том, что теряется строгая типизация. В строковое поле можно передать что угодно, а хотелось бы, чтобы на стороне клиента сгенерировался строгий Java Enum, исключающий передачу некорректных статусов.
Чтобы решить эту задачу, применим механизм Фасетов (ограничений типа) в XDTO. Проанализируем по шагам, как это правильно настроить:
OrderStatusEnum.string из пространства имен http://www.w3.org/2001/XMLSchema.XMLСтрока() для соответствующих элементов перечисления 1С.В коде обработчика веб-сервиса присвоение значения такому полю будет выглядеть стандартно:
OrderXDTO.status = XMLСтрока(элРезультат.СтатусЗаказа);
Что это дает? При таком подходе ФабрикаXDTO сама проверит, входит ли полученная строка в список разрешенных в фасете значений. А главное — при публикации веб-сервиса платформа 1С корректно сгенерирует в WSDL/XSD схеме классическое ограничение типа (restriction). В XML-разметке контракта это преобразуется в блок с тегами enumeration.
Когда генераторы кода на стороне Java (например, утилита wsimport) прочитают такой WSDL, они автоматически распознают паттерн ограничения строки и создадут в клиентском коде полноценный строгий Enum. Клиент больше не увидит внутренностей пакета current-config, но при этом получит жесткий контракт с конечным набором допустимых статусов.