суббота, 21 сентября 2013 г.

1С:Предприятие 8. Веб-сервисы. Фасеты как способ ограничить значения данных


Содержание статей: 1С:Предприятие 8. Веб-сервисы
Предыдущая статья: 1С:Предприятие 8. Веб-сервисы. Возвращаем массив

Фасеты - это определенные ограничения на тип значений XDTO. Один фасет определяет тип ограничения и значение ограничения. Например [Максимум включающий - 5]. Тип значения XDTO может хранить в себе несколько фасетов, но их типы должны быть уникальны, то есть нельзя указать два фасета   [Максимум включающий - 5] и [Максимум включающий - 3].

В данной статье хочу показать как можно при помощи фасетов сделать проверку входных и как сделать параметр ws-операции составного типа.

Поставим простую задачу - сделать выгрузку номенклатуры через веб-сервис. Будем выгружать код, наименование, цену и остаток в магазине. Но справочник может быть очень большим, потому при вызове ws-операции должна быть возможность установить отбор. Будем отбирать по коду номенклатуры.

Создадим новую базу и добавим новый пакет XDTO, назовем его  ПакетXDTO, укажем пространство имен.
1С: фасеты в веб-сервисах

Далее добавим в пакет Тип значения как показано на рисунке.
1С: фасеты в веб-сервисах

Давайте создадим тип "Код" для организации отбора по уникальному идентификатору номенклатуры. Соответственно, новый тип "Код" можно получить из типа string, добавив ограничение на количество символов. Символов должно быть 9, то есть количество символов в коде номенклатуры. Для фасета "Пробельные символы" установим значение "collapse", это позволит вывести ошибку, если в коде имеются пробелы.
1С: фасеты в веб-сервисах

Теперь таким же образом создадим ТипЗначения "Цена". Для него установим минимум 0, максимум 1 000 000.

1С: фасеты в веб-сервисах

Для решения задачи создадим справочник номенклатуры, остатки будем хранить в одном из его реквизитов - это не принципиально.
1С: фасеты в веб-сервисах

Ну, теперь приступим к созданию веб-сервиса. Назовем его "Остатки" и добавим 3 параметра:
  • Код - тип Код, который мы ранее создали. По данному параметру будем устанавливать отбор на код номенклатуры;
  • ЦенаОт - тип Цена. Это нижняя граница цены товара;
  • ЦенаДо - тип Цена. Это верхняя граница цены товара.
1С: фасеты в веб-сервисах

Для того что бы веб сервис вывел массив товаров, у каждого из которых есть код, наименование, цена и остаток создадим ОбъектXDTO "Номенклатура", в котором укажем поля:
  • Код - тип Код;
  • Наименование - тип string;
  • Цена - тип Цена;
  • Остаток - тип int
И создадим ОбъектXDTO "Товары", который будет иметь одно свойство "Номенклатура", но с возможностью вывода списком. В качестве типа поля "Номенклатура" объекта "Товары" укажите объект "Номенклатура". Подробнее о том как передать массив через веб-сервис можно прочитать тут.
1С: фасеты в веб-сервисах

Перейдем к свойствам операции "Остатки". Укажем тип возвращаемого значения - "Товары" и откроем ее модуль.  Напишем такой код:

Функция Остатки(Код, ЦенаОт, ЦенаДо)

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
| Номенклатура.Код,
| Номенклатура.Наименование,
| Номенклатура.Цена,
| Номенклатура.Остаток
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| 1 = 1
| И 2 = 2";

Если ЗначениеЗаполнено(Код)
И Код<>"000000000" Тогда
Запрос.Текст = СтрЗаменить(Запрос.Текст, "1 = 1","Номенклатура.Код = &Код"); 
Запрос.УстановитьПараметр("Код", Код);
КонецЕсли;

Если НЕ ЦенаОт = ЦенаДо  Тогда
Запрос.Текст = СтрЗаменить(Запрос.Текст, "2 = 2","Номенклатура.Цена МЕЖДУ &ЦенаОт И &ЦенаДо");
Запрос.УстановитьПараметр("ЦенаДо", ЦенаДо);
Запрос.УстановитьПараметр("ЦенаОт", ЦенаОт);
КонецЕсли;

РезультатЗапроса = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
ТипXDTOТовары = ФабрикаXDTO.Тип("http://codenotes-1c.blogspot.ru/", "Товары");   

Товары = ФабрикаXDTO.Создать(ТипXDTOТовары);
ТипXDTOНоменклатура = ФабрикаXDTO.Тип("http://codenotes-1c.blogspot.ru/", "Номенклатура");

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Номенклатура = ФабрикаXDTO.Создать(ТипXDTOНоменклатура);
Номенклатура.Код = ВыборкаДетальныеЗаписи.Код;
Номенклатура.Наименование = ВыборкаДетальныеЗаписи.Наименование;
Номенклатура.Цена = ВыборкаДетальныеЗаписи.Цена;
Номенклатура.Остаток = ВыборкаДетальныеЗаписи.Остаток;
Товары.Номенклатура.Добавить(Номенклатура);
КонецЦикла;

Возврат Товары;

КонецФункции

Для демонстрации работы фасетов сам код смотреть не обязательно, сейчас важно проверить, что без кодирования ограничений на входные параметры они присутствуют благодаря фасетам.
Для этого вызовем ws-операцию с различными параметрами:
  • без параметров. Если быть точным то укажем код "000000000", цену от =0, цену до = 0. Потому что, пустые параметры недопустимы.
1С: фасеты в веб-сервисах

  • передадим в качестве кода "001" и получим сообщение об ошибке
1С: фасеты в веб-сервисах
  • передадим в качестве "ЦенаОт" отрицательное число и так же получим ошибку
1С: фасеты в веб-сервисах
  • передадим параметр "ЦенаДо" равный 2 000 000 и снова получим сообщение об ошибке
1С: фасеты в веб-сервисах


Усложним задачу. Предположим, что код номенклатуры может быть как строковым так и числовым. Вот тут нам пригодится возможность объединять типы значений в один, включая их фасеты.

Давайте создадим новый ТипЗначения "КодИЦифра". У него укажем в свойстве "Вариант" "Объединение", а в свойстве "Типы объединения" перечислим те типы, которые хотим объединить.
1С: фасеты в веб-сервисах
Ну и у параметра "Код" ws-операции "Остатки" укажем этот тип. После чего мы сможем указывать код номенклатуры как в виде числа, так и в виде строки. Без переделки кода можем указать только 0, что соответствует пустому значению параметра, и отбор не будет установлен.

1С: фасеты в веб-сервисах

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

Далее, в качестве справки приведу значение каждого поля свойства. Данное описание  взято по ссылке: К чему относится понятие «Фасет» в рамках модели XDTO? Что такое фасет? Авторам большое спасибо!
  • Базовый тип - тип, который используется как основа. По умолчанию anyType. От этого значения зависит допустимый набор фасетов.
  • Длина — фасет длины. Содержит количество единиц длины, причем единица длины имеет различный смысл для различных типов. Для типов «string» и «anyURI» длина содержит количество символов. Для типов «hexBinary» и «base64Binary» длина содержит количество байт двоичных данных. Для типов, определяемых списком, длина содержит количество элементов списка;
  • МаксВключающее — фасет максимума, включающего границу. Ограничивает пространство значений данного типа максимальным значением. Любое значение данного типа меньше либо равно указанному значению;
  • МаксДлина — фасет максимальной длины. Содержит максимальное количество единиц длины, причем единица длины имеет различный смысл для различных типов. Для типа «string» максимальная длина содержит максимальное количество символов. Для типов «hexBinary» и «base64Binary» максимальная длина содержит максимальное количество байт двоичных данных. Для типов, определяемых списком, максимальная длина содержит максимальное количество элементов списка;
  • МаксИсключающее — фасет максимума, не включающего границу. Ограничивает пространство значений данного типа максимальным значением. Любое значение данного типа меньше указанного значения;
  • МинВключающее — фасет минимума, включающего границу. Ограничивает пространство значений данного типа минимальным значением. Любое значение данного типа больше либо равно указанному значению;
  • МинДлина — фасет минимальной длины. Содержит минимальное количество единиц длины, причем единица длины имеет различный смысл для различных типов. Для типа «string» минимальная длина содержит минимальное количество символов. Для типов «hexBinary» и «base64Binary» минимальная длина содержит минимальное количество байт двоичных данных. Для типов, определяемых списком, минимальная длина содержит минимальное количество элементов списка;
  • МинИсключающее — фасет минимума, не включающего границу. Ограничивает пространство значений данного типа минимальным значением. Любое значение данного типа больше указанного значения;
  • Перечисление — фасет перечисления. Определяет набор допустимых значений данного типа;
  • ПробельныеСимволы — фасет пробельных символов. Может принимать одно из трех значений:
    • Сохранять — строка может содержать любые пробельные символы;
    • Заменять — строка не должна содержать #x9 (табуляция), #xA (перевод строки) и #xD (возврат каретки). Если они существуют, то они должны быть заменены символом #x20 (пробел);
    • Сворачивать — дополнительно к требованиям, указанным для значения replace, строка не должна содержать парных символов #x20 (пробел), а также лидирующих и завершающих символов #x20 (пробел);
  • ЦифрВсего — фасет общего количества цифр. Содержит общее количество разрядов числа (целая часть плюс дробная часть);
  • ЦифрДробнойЧасти — фасет количества цифр дробной части. Содержит количество разрядов дробной части числа.
Информационную базу модно скачать по этой ссылке.

2 комментария: