В этой статье рассмотрим, как можно реализовать веб-сервис в расширении платформы 1С.
В качестве примера возьмем веб-сервис, позволяющий передавать информацию о клиентах из внешней CRM-системы во внутреннюю систему управленческого учета на «1С:Управление нашей фирмой».
Веб-сервис будет создан в расширении, чтобы сохранить конфигурацию на поддержке.
О чем эта статья
Материал статьи раскроет ответы на следующие вопросы:
- Как работать с XDTO-пакетами?
- Как создать веб-сервис и настроить его свойства?
- Как опубликовать веб-сервис на сервере?
Постановка задачи
Компания ведет учет в типовом решении фирмы «1С:Управление нашей фирмой» (УНФ). Для управления взаимоотношениями с клиентами используется облачная CRM-система. В CRM-систему вводят информацию о новых клиентах. Необходимо реализовать перенос сведений о новых клиентах в УНФ сразу же при регистрации данных в CRM-системе.
Рисунок 1. Схема работы
Данные должны передаваться одним параметром (структурой). Спецификация данных, передаваемые из CRM в УНФ приведены в таблице 1.
Таблица 1. Требования к данным для обмена
Данные | Имя cвойства | Тип | Ограничения |
Полное наименование | FullName | Строка | Обязательно для заполнения |
ИНН | INN | Строка(12) | Для ЮрЛица – длина 10 Для ИП – длина 12 Для ФизЛица – не заполняется Допускаются только цифры |
КПП | KPP | Строка(9) | Для ЮрЛица – длина 9 Для ФизЛица – не заполняется Допускаются только цифры |
Телефон | Phone | Строка(12) | Обязателен для заполнения формат +7 (NNN) NNN-NN-NN |
После создания контрагента в CRM-систему должен быть передан уникальный идентификатор. Идентификатор будет использоваться в дальнейшем для сопоставлении клиента в CRM и УНФ при обмене заказами. Необходимо реализовать описанный функционал без снятия УНФ с поддержки.
Обоснование выбора варианта решения
- Проанализируем требования. Добавлять клиентов надо «на лету», сразу же при вводе в CRM. Значит периодические обмены по расписанию нам не подходят.
- Выбранная CRM расположена в облаке, поэтому использовать COM-соединение не получится.
- В требованиях к передаваемым данным есть ограничения — на длину строк и на виды контрагентов. Выбирая между технологией обмена через http-сервисы и веб-сервисы, остановимся на веб-сервисах, так как типизация данных и настройка ограничений в них есть «из коробки». Дополнительным плюсом будет то, что веб-сервисы умеют «самодокументироваться», а значит мы экономим время на описании API для разработчиков CRM.
- Последнее требование — не снимать конфигурацию с поддержки.
Таким образом, для решения описанной задачи мы создадим расширение конфигурации. А в этом расширении реализуем веб-сервис для добавления информации о контрагентах.
Добавляем расширение
Начнем реализацию поставленной задачи и создадим новое расширение. Для этого откроем меню Конфигурация -> Расширения конфигурации.
Рисунок 2. Добавляем расширение
В открывшемся окне жмем кнопку Добавить, а затем заполняем окно создания расширения.
Рисунок 3. Заполняем свойства нового расширения
Префикс указывается для обеспечения уникальности расширений. Обычно в качестве префикса используют первые буквы названия компании или инициалы разработчика. Сохраним расширение, нажав ОК, а затем дважды щелкнем по строке расширения, чтобы его открыть.
Импортируем объекты метаданных
Теперь импортируем в расширение объекты для дальнейшей работы. Нам нужны:
- Справочник Контрагенты
- Справочник Виды контактной информации
- Перечисление Типы контактной информации
Начнем со справочника Контрагенты. Выделим его в основной конфигурации и вызовем контекстное меню Добавить в расширение.
Рисунок 4. Импортируем справочник
Затем добавим в расширение реквизиты справочника Контрагенты и табличную часть КонтактнаяИнформация.
В результате ветка Контрагенты в расширении должна выглядеть так:
Рисунок 5. Справочник «Контрагенты» в расширении
После чего добавим в расширение перечисления ВидыКонтрагентов и ТипыКонтактнойИнформации.
Идем дальше. Из справочника ВидыКонтактнойИнформации нам нужно предопределенное значение ТелефонКонтрагента. Выдяем в дереве метаданных справочник ВидыКонтактнойИнформации и переходим по гиперссылке Предопределенные:
Рисунок 6. Предопределенные элементы справочника
В ветке Контрагенты находим предопределенный элемент ТелефонКонтрагента.
Рисунок 7. Выбираем предопределенный элемент ТелефонКонтрагента
Выполняем команду контекстного меню Добавить в расширение. В расширение добавляется справочник ВидыКонтактнойИнформации и его предопределенный элемент ТелефонКонтрагента.
Рисунок 8. Справочник «Виды контактной информации» в расширении
С импортом объектов в расширение мы закончили. Теперь переходим к разработке веб-сервиса.
Как работают веб-сервисы
Веб-сервисы в 1C представляют собой реализацию протокола SOAP (от англ. Simple Object Access Protocol — простой протокол доступа к объектам). Архитектуру приложения на основе протокола SOAP можно представить в виде следующей схемы:
Рисунок 9. Архитектура приложений на основе протокола SOAP
Общий принцип работы веб-сервиса можно описать так: мы создаем некий функционал, чтобы предоставить его сторонним разработчикам. Для того, чтобы этот функционал был им доступен, мы размещаем его на веб-сервере (публикуем). При публикации веб-сервиса происходит размещение его описания в формате WSDL (WSDL – Web Service Definition Language). Это описание стандартизовано и содержит описание методов веб-сервиса и типов данных, которые могут передаваться между сервисом и его клиентом. Клиент сервиса получает описание сервиса в виде WSDL-файла и может начать обмениваться данными в соответствии с этим описанием. Обмен происходит по протоколу HTTP, а сообщения передаются в теле HTTP пакетов в формате XML.
Особенность этой технологии состоит в том, что нам не нужно формировать XML и HTTP-пакеты вручную. Современные среды разработки, в том числе и 1С, позволяют работать с веб-сервисами в объектной технике.
Создаем XDTO-пакет
XDTO-пакеты описывают типы данных, которые будут использоваться при обмене. Потребителями веб-сервисов могут быть программы, написанные на разных языках, поэтому веб-сервис должен представить свои данные в виде примитивных типов (их описание во всех языках равнозначно). XDTO-пакеты позволяют привести типы 1С к типам, которые описаны в общемировом стандарте W3C. Кроме того, мы можем описать набор ограничений, применяемых к данным.
Приступаем к созданию XDTO-пакета для нашего веб-сервиса. В дереве метаданных расширения в ветке Общие -> XDTO-пакеты добавим XDTO-пакет ak_Customers. В URI пространства имен указываем http://kursy-po-1c.ru/ws/wsextension.
Это не ссылка на реальный адрес в интернете, а просто строка-идентификатор пространства имен, который помогает однозначно идентифицировать типы данных с одинаковыми именами. Например, программист Иванов определил тип данных Customer c двумя свойствами Name и FullName, а программист Петров определил свой тип Customer со свойствами Name, INN, KPP.
Чтобы не возникало путаницы и проблем с одинаковыми названиями типов, применяются пространства имен. Пространство имен и имя типа должны однозначно идентифицировать тип данных. При описании типов данных для веб-сервисов принято в качестве пространства имен использовать URI, содержащие доменное имя разработчика. Это позволяет сделать пространство имен уникальным.
Рисунок 10. Свойства XDTO-пакета
Теперь жмем ссылку Открыть пакет и начинаем описывать типы данных.
Сначала опишем простые типы данных по которым нам нужно наложить ограничения. Это ИНН, КПП, Телефон.
ИНН по условиям задачи различается для ИП и для ЮрЛица.
Определим 2 простых типа: INN_IP и INN_UL. Для этого в форме редактирования пакета открываем меню Добавить -> ТипЗначения.
Рисунок 11. Добавляем тип значения в XDTO-пакет
Заполняем свойства как на рисунке ниже:
Рисунок 12. Свойства типа значения INN_IP
Здесь мы указали имя типа INN_IP (ИНН для ИП) и определили для него ограничение — это должна быть строка длиной 12 знаков.
Обратите внимание, что для названий типов веб-сервиса нужно выбирать англоязычные имена. В дальнейшем они будут использоваться на стороне клиента для генерации классов, а с кириллицей где-то могут возникнуть сложности.
Теперь нам нужно задать ограничение: 12 знаков должны быть цифрами. Выделяем свойство INN_IP и вызываем меню Добавить->Образец:
Рисунок 13. Добавляем шаблона заполнения INN_IP
Заполняем свойство образца шаблоном в виде регулярного выражения [0-9]{12}. То есть мы допускаем в значении 12 цифр от 0 до 9.
Рисунок 14. Шаблон заполнения INN_IP
Подобные действия нужно произвести с INN_UL (ИНН юрлица) и KPP (КПП):
Рисунок 15. Добавляем типы значений и устанавливаем шаблоны
И для телефона (шаблон [+][7][ ][(][0-9]{3}[)][ ][0-9]{3}[-][0-9]{2}[-][0-9]{2}):
Рисунок 16. Типа значения Phone и шаблон его заполнения
Теперь перейдем к определению типов для данных о клиентах.
У нас есть три типа клиентов: Юрлицо, ФизЛицо и ИП. Для всех типов клиентов правила заполнения ИНН и КПП отличаются. Можно сделать только один класс Customer и контроль заполнения ИНН и КПП производить программно, но удобнее это делать декларативно — чтобы уменьшить возможность ошибок. Мы создадим три комплексных типа: CustomerIP, CustomerUL и CustomerFL. Значения ИНН и КПП будем выбирать из ранее созданных типов значений.
Для создания клиента ФизЛицо выделим корень пакета и вызовем меню Добавить -> ТипОбъекта. В свойствах укажем следующие значения:
Рисунок 17. Свойства типа объекта CustomerFL
- CustomerFL — это имя типа. Должно быть на английском.
- ComplexType — базовый тип, аналогичный структуре.
Выделим тип объекта CustomerFL и вызовем меню Добавить->Свойство. Заполним в редакторе свойств значения:
Рисунок 18. Добавляем свойство FullName в тип объекта CustomerFL
- FullName — имя свойства. Должно быть на английском.
- Тип string — строковый тип.
- Поле FullName должно быть обязательно заполнено указываем Возможно пустое — Ложь.
Таким же образом добавим свойства Phone и GUID.
Рисунок 19. Добавляем свойство Phone в тип объекта CustomerFL
Рисунок 20 Добавляем свойство GUID в тип объекта CustomerFL
Затем добавим тип объекта CustomerIP с такими же свойствами, как у CustomerFL, добавив новое свойство INN.
Рисунок 21. Добавляем свойство INN в тип объекта CustomerIP
Дальше создадим тип объекта CustomerUL с такими же свойствами, как у CustomerIP. Добавим новое свойство KPP.
Рисунок 22. Добавляем свойство KPP в тип объекта CustomerUL
У свойства INN нужно изменить тип на INN_UL (http://kursy-po-1c.ru/ws/wsextension).
Рисунок 23. Добавляем свойство INN в тип объекта CustomerUL
Мы завершили создание XDTO-пакета.
Рисунок 24. Новый XDTO-пакет
Переходим к разработке веб-сервиса.
Создаем веб-сервис
В ветке метаданных Общие выделяем ветку Web-Сервисы. Вызываем контекстное меню Добавить и заполняем свойства нового веб-сервиса:
Рисунок 25. Заполняем свойства веб-сервиса
- Имя — ak_Customers
- ПакетыXDTO — http://kursy-po-1c.ru/ws/wsextension. Теперь сможем использовать типы данных, которые определены этом пакете.
- URI пространства — http://kursy-po-1c.ru/ws/wsextension. Пространство имен будет использоваться клиентами веб-сервиса.
- Имя файла публикации — Customers.1cws. Имя будет использоваться в URL для получения WSDL.
Теперь добавим метод веб-сервиса, который будет записывать в УНФ нового контрагента-физлицо. Вызываем меню Добавить->Операция и заполняем свойства:
Рисунок 26. Свойства метода AddCustomerFL
- Имя — имя метода веб-сервиса. Будет использоваться при обращении к сервису извне.
- Тип возвращаемого значения — тип данных, который возвращает сервис. В нашем случае это строка-уникальный идентификатор, который в будет возвращен в CRM.
- Имя процедуры — имя процедуры в модуле сервиса, которая будет выполняться при обращении к этому методу.
Далее мы добавим параметры, которые будут передаваться в веб-сервис.
В нашем случае это один параметр — Customer. Для добавления параметра выделяем операцию веб-сервиса и вызываем контекстное меню Добавить->Параметр. В свойствах этого параметра заполняем свойства:
Рисунок 27. Свойства параметра Customer
- Имя — имя параметра метода сервиса. Будет виден на клиенте веб-сервиса.
- Тип значения — тип значения, определенный в нашем пакете.
Добавим еще две операции:
- AddCustomerIP
- AddCustomerUL.
Можно сделать это копированием. Затем нужно поменять имена операций, имена процедур-обработчиков (AddCustomerIP и AddCustomerUL) и типы параметров. Для AddCustomerIP тип параметра установим CustomerIP, а для AddCustomerUL — CustomerUP.
Теперь нужно создать процедуры-обработчики методов сервиса.
//Добавляем ФизЛицо Функция AddCustomerFL(Customer) Возврат ДобавитьКлиента(Customer, Перечисления.ВидыКонтрагентов.ФизическоеЛицо); КонецФункции //Добавляем ЮрЛицо Функция AddCustomerUL(Customer) Возврат ДобавитьКлиента(Customer, Перечисления.ВидыКонтрагентов.ЮридическоеЛицо); КонецФункции //Добавляем ИП Функция AddCustomerIP(Customer) Возврат ДобавитьКлиента(Customer, Перечисления.ВидыКонтрагентов.ИндивидуальныйПредприниматель); КонецФункции //Добавляем контрагента в базу УНФ Функция ДобавитьКлиента(Клиент, ВидКонтрагента) //Создаем нового контрагента и заполняем общие реквищиты НовыйКлиент = Справочники.Контрагенты.СоздатьЭлемент(); НовыйКлиент.ВидКонтрагента = ВидКонтрагента; НовыйКлиент.Наименование = Клиент.FullName; НовыйКлиент.НаименованиеПолное = Клиент.FullName; НовыйКлиент.Покупатель = Истина; //Для ЮрЛица и ИП заполняем ИНН Если ВидКонтрагента <> Перечисления.ВидыКонтрагентов. ФизическоеЛицо Тогда НовыйКлиент.ИНН = Клиент.INN; КонецЕсли; //Для ЮрЛица заполняем КПП Если ВидКонтрагента = Перечисления.ВидыКонтрагентов.ЮридическоеЛицо Тогда НовыйКлиент.КПП = Клиент.KPP; КонецЕсли; //Заполняем контактные данные Телефон = НовыйКлиент.КонтактнаяИнформация.Добавить(); Телефон.Тип = Перечисления.ТипыКонтактнойИнформации.Телефон; Телефон.Вид = Справочники.ВидыКонтактнойИнформации.ТелефонКонтрагента; Телефон.НомерТелефона = Клиент.Phone; Телефон.Представление = Клиент.Phone; //Записываем клиента в базу НовыйКлиент.Записать(); //Возвращаем ссылку в виде уникального идентификатора (GUID) Возврат XMLСтрока(НовыйКлиент.Ссылка); КонецФункции
Код простой и каких-то особых комментариев не требует.
Публикуем веб-сервис на сервере
Для публикации веб-сервиса должны быть установлены:
- Веб-сервер (Apache или IIS)
- Платформа 8.3.7 и выше с установленным расширением веб-сервера
О подготовке рабочего окружения можно прочитать в статье Как настроить обмен 1С с интернет-сервисами.
Для публикации веб-сервиса нужно запустить конфигуратор с правами администратора. Для этого вызываем контекстное меню и выбираем «Запуск от имени администратора»:
Рисунок 28. Запускаем конфигуратор от имени администратора
После открываем меню Администрирование->Публикация на веб-сервере. В открывшемся окне заполняем настройки:
Рисунок 29. Публикация веб-сервиса
- Имя — имя базы для публикации на сервере. Будет являться частью URL.
- Веб-сервер — на нем будет опубликована база. В нашем случае используется Apache 2.4.
- Каталог — место на диске, куда будет помещен default.vrd.
- Публиковать веб-сервисы — отмечаем.
- Публиковать веб-сервисы расширений по умолчанию — отмечаем, чтобы веб-сервисы были доступны из расширений.
Жмем Опубликовать.
Проверим, что веб-сервис опубликовался. Для этого запустим браузер и в адресной строке введем http://localhost/UNF/ws/Customers.1cws?wsdl. В результате в браузере должен отобразиться XML.
Рисунок 30. Проверяем работу веб-сервиса
Если в вашей базе есть пользователи, то при обращении по указанной ссылке будет запрошен логин и пароль. Нужно ввести логин и пароль администратора информационной базы.
Чтобы в дальнейшем не отвлекаться на пароли при изучении статьи (тему безопасности мы сознательно опускаем), откроем в текстовом редакторе файл default.vrd, (он лежит в каталоге, указанном при публикации). В него запишем логин и пароль в строке подключения: ib=”File="D:\1CBase\UNF";usr=admin;pwd=12345;”. Логин, пароль и путь должны быть от вашей базы 1С.
Тестируем веб-сервис
Для проверки работоспособности сервера можно создать отдельную базу 1С и добавить в ней обработку ТестВебСервера со следующими реквизитами:
- FullName, строка(100)
- INN, строка(12)
- KPP, строка(9)
- Phone, строка(20)
Реквизиты выводим на форму и добавляем три кнопки:
- Создать ФизЛицо
- Создать ЮрЛицо
- Создать ИП.
Рисунок 31. Обработка для проверки веб-сервиса
В модуле формы напишем такой код:
//1. Обработчики кнопок //Обработчик кнопки СоздатьФизЛицо &НаКлиенте Процедура СоздатьФизЛицо(Команда) СоздатьКлиентаНаСервере("CustomerFL"); КонецПроцедуры //Обработчик кнопки СоздатьИП &НаКлиенте Процедура СоздатьИП(Команда) СоздатьКлиентаНаСервере("CustomerIP"); КонецПроцедуры //Обработчик кнопки СоздатьЮрЛицо &НаКлиенте Процедура СоздатьЮрЛицо(Команда) СоздатьКлиентаНаСервере("CustomerUL"); КонецПроцедуры //Создание клиента &НаСервере Процедура СоздатьКлиентаНаСервере(ТипКлиента) //2. Получаем описание сервиса ВСОпределение = Новый WSОпределения("http://localhost/UNF/ws/Customers.1cws?wsdl"); //3. Создаем прокси для обращения к сервису Прокси = Новый WSПрокси(ВСОпределение, "http://http://kursy-po-1c.ru">kursy-po-1c.ru/ws/wsextension", "ak_Customers", "ak_CustomersSoap"); //4. Получаем тип клиента по URI пространству имен и имени типа ТипКлиент = Прокси.ФабрикаXDTO.Тип("http://http://kursy-po-1c.ru">kursy-po-1c.ru/ws/wsextension", ТипКлиента); //5. Создаем XDTOОбъект заданного типа Клиент = Прокси.ФабрикаXDTO.Создать(ТипКлиент) ; //6. Заполняем данные Клиента данными, введенными в форме ЗаполнитьЗначенияСвойств(Клиент, Объект); //7. В зависимости от типа клиента вызываем соответствующий метод веб-сервиса Если ТипКлиента = "CustomerFL" Тогда Объект.GUID = Прокси.AddCustomerFL(Клиент); ИначеЕсли ТипКлиента = "CustomerIP" Тогда Объект.GUID = Прокси.AddCustomerIP(Клиент); ИначеЕсли ТипКлиента = "CustomerUL" Тогда Объект.GUID = Прокси.AddCustomerUL(Клиент); КонецЕсли; КонецПроцедуры
Прокомментируем код:
- В обработчиках кнопок вызываем процедуру СоздатьКлиентаНаСервере() и передаем название типа клиента в виде строки.
- Получаем WSDL-описание веб сервиса, опубликованного по указанному в параметрах URL. На основании него создается объект WSОпределение.
- Создаем объект Прокси для работы с сервисом. Он позволяет обращаться к веб-сервису, вызывая его методы в привычном объектном стиле. В качестве параметров передаем WSОпределение сервиса, созданное на предыдущем шаге, пространство имен веб-сервиса, имя веб-сервиса и точку подключения. Имя точки подключения формируется путем добавления к имени сервиса суффикса Soap (так формирует WSDL 1C).
- Получаем тип клиента по URI пространства имен.
- На основании типа клиента, полученного на предыдущем шаге, создаем XDTOОбъект Клиент. По структуре этот объект будет соответствовать структуре типа, который мы определяли в нашем XDTO-пакете.
- Заполняем значения реквизитов клиента данными, введенными в форме;
- В зависимости от переданного в процедуру типа клиента, мы вызываем разные методы веб-сервиса. «Под капотом» этого вызова произойдет сериализация данных в XML, валидация XML, формирование HTTP пакета и отправка его на сервер.
С этой обработкой можно поэксперементировать. Попробуйте создавать клиентов разных типов, введя корректные данные и некорректные. Если вы попытаетесь ввести в ИНН буквы или заполнить телефон, не соблюдая формат, то появится окно ошибки.
Итак, в данной статье мы познакомились с возможностями платформы по разработке веб-сервисов без снятия конфигурации с поддержки. Создали расширение, импортировали в расширение нужные нам объекты метаданных и описали модель данных для обмена. Создали и опубликовали веб-сервис. Написали обработку на 1С для проверки работоспособности этого сервиса.
На этом пока закончим, но не остановимся :-)
Коментарі
Дописати коментар