Все что нужно для работы с WSDL

Author Автор: Роман Чернышов    Опубликовано: 7 марта 2022

wsdl soap xml Доброго времени друзья! Сегодня я хочу поделиться небольшой статьей-заметкой, на тему работы с WSDL языком описания веб-сервисов и доступа к ним, работающего по протоколу SOAP, который очень часто используется во взаимодействии различных, распроданных веб-сервисов и API(англ. Application Programming Interface — программный интерфейс приложения). Мне часто приходится работать с ним в рамках интеграции платформ по страхованию со страховыми компаниями(Пари, Ингосстрах), для реализации функционала автоматической продажи страховых полисов. И так как, очень часто, поддержка со стороны интегрируемых сервисов, кроме как ссылки на сервер WSDL и скудного описания, больше ничего не предоставляет, очень важно научиться разбираться и работать с имеющимися службами и их данными, самостоятельно. В чем, я надеюсь, будет полезна моя статья.

WSDL

Рассмотрим что такое WSDL (англ. Web Services Description Language) — язык описания веб-сервисов и доступа к ним, основанный на языке XML. Получив ссылку на WSDL сервер, мы можем запросить от него документ на языке XML, который будет содержать в себе описание всех методов доступа к сервису(запросов), их переменных и свойств, типов запросов, также в нем будут описаны параметры ответов и их содержание. Можно сказать, что WSDL это и есть та самая документация, описывающая то, как работать с API сервиса, но есть единственное — но, описание это дается на языке XML, и вникать в его код, открыв документ в редакторе, становиться очень сложной, порою, непосильной задачей. Поэтому, для изучения описания методов работы с API, мы воспользуемся специальным инструментом SoapUI, но об это позже.

Особенность WSDL сервера, состоят в том, что он имеет двойное назначение(в отличии например от REST выполняющего только функцию обмена данными в обе стороны, или в одну работая асинхронно), во первых он передает нам(на языке XML) описание(документацию) о том как взаимодействовать с ним, а во вторых он же позволяет нам обмениваться с ним сообщениями, оформленными по правилам этой самой документации. Также в отличии от REST(если вы раньше с ним работали), WSDL имеет одну точку входа(один единственный адрес сервера и URL, у REST на каждый запрос свой URL). Надеюсь тут все понятно? (для введения этого достаточно)

А пока, давайте все же немного задержимся на WSDL, как я и сказал, изучать доступные методы и свойства читая исходный XML код полученный от WSDL сервера, та еще задачка, но базовое представление о структуре XML документа, мы все же должны иметь. Надеюсь вы знакомы с XML, если же нет то вот тут можно это исправить.

Структура

Для работы с XML кодом WSDL, а также для создания запросов и получения ответов от сервера WSDL(которые представляют собой сообщения на языке XML), нужно понимать их базовую структуру, имеющую следующие логические части:

  • определение типов данных (types) — определение вида отправляемых и получаемых сервисом XML-сообщений
  • элементы данных (message) — сообщения, используемые web-сервисом
  • абстрактные операции (portType) — список операций, которые могут быть выполнены с сообщениями
  • связывание сервисов (binding) — способ, которым сообщение будет доставлено

Ниже представлен пример XML кода, документации WSDL сервиса, с описанием запроса к серверу и его ответа (в реальности документ может содержать тысячи строк):

<message name="getTermRequest">
   <part name="term" type="xs:string"/>
</message>
 
<message name="getTermResponse">
   <part name="value" type="xs:string"/>
</message>
 
<portType name="glossaryTerms">
  <operation name="getTerm">
      <input message="getTermRequest"/>
      <output message="getTermResponse"/>
  </operation>
</portType>

Вот пример XML кода для запроса на WSDL сервер, для выполнения метода CreateInsuranceContract (Метод создание договора страхования в стразовой компании Пари, по продукту страхования ипотеки). В документе приводиться как описание запрашиваемого метода, так и список передаваемых параметров. Отдельно отмечены те параметры, которые являются необязательными(Optional). Отправив такой запрос на WDSL сервер, мы дадим службе, команду на создание договора страховая и передадим для этого все необходимые параметры. То, как должен выглядеть запрос и какие параметры он может при этом содержать, ранее нам сообщил сам же WSDL сервер, на который мы и шлем запрос.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:sit="http://schemas.datacontract.org/2004/07/SiteIntegrationWCF.DataContracts.Request" xmlns:sit1="http://schemas.datacontract.org/2004/07/SiteIntegrationWCF.DataContracts.DataObjects">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:CreateInsuranceContract>
         <!--Optional:-->
         <tem:request>
            <!--Optional:-->
            <sit:AddressInsuranceObject>
               <!--Optional:-->
               <sit1:Apartment>?</sit1:Apartment>
               <!--Optional:-->
               <sit1:Area>?</sit1:Area>
               <!--Optional:-->
               <sit1:Build>?</sit1:Build>
               <sit1:City>?</sit1:City>
               <!--Optional:-->
               <sit1:FullAddress>?</sit1:FullAddress>
               <sit1:Street>?</sit1:Street>
               <!--Optional:-->
               <sit1:InsuranceObjectShare>?</sit1:InsuranceObjectShare>
               <!--Optional:-->
               <sit1:InsuranceTitleShare>?</sit1:InsuranceTitleShare>
               <!--Optional:-->
               <sit1:ScheduleInsuranceObject>
                  <!--Optional:-->
                  <sit1:Periods>
                     <!--Zero or more repetitions:-->
                     <sit1:Period>
                        <!--Optional:-->
                        <sit1:DateEndPeriod>?</sit1:DateEndPeriod>
                        <!--Optional:-->
                        <sit1:DateStartPeriod>?</sit1:DateStartPeriod>
                        <!--Optional:-->
                        <sit1:Tariffs>
                           <!--Zero or more repetitions:-->
                           <sit1:Tariff>
                              <!--Optional:-->
                              <sit1:Amount>?</sit1:Amount>
                              <sit1:InsuranceType>?</sit1:InsuranceType>
                              <!--Optional:-->
                              <sit1:PeriodEnd>?</sit1:PeriodEnd>
                              <!--Optional:-->
                              <sit1:PeriodStart>?</sit1:PeriodStart>
                              <!--Optional:-->
                              <sit1:Premium>?</sit1:Premium>
                              <!--Optional:-->
                              <sit1:Rate>?</sit1:Rate>
                           </sit1:Tariff>
                        </sit1:Tariffs>
                     </sit1:Period>
                  </sit1:Periods>
               </sit1:ScheduleInsuranceObject>
            </sit:AddressInsuranceObject>
            <!--Optional:-->
            <sit:AgreementDate>?</sit:AgreementDate>
            <sit:AgreementNumber>?</sit:AgreementNumber>
            <!--Optional:-->
            <sit:BusinessUnitId>?</sit:BusinessUnitId>
            <!--Optional:-->
            <sit:ConclusionDate>?</sit:ConclusionDate>
            <!--Optional:-->
            <sit:ContractNumber>?</sit:ContractNumber>
            <!--Optional:-->
            <sit:CreditSum>?</sit:CreditSum>
            <sit:CreditorId>?</sit:CreditorId>
            <sit:DateEnd>?</sit:DateEnd>
            <sit:DateStart>?</sit:DateStart>
            <!--Optional:-->
            <sit:Documents>
               <!--Zero or more repetitions:-->
               <sit1:Document>
                  <!--Optional:-->
                  <sit1:DocumentText>?</sit1:DocumentText>
                  <!--Optional:-->
                  <sit1:IsForm>?</sit1:IsForm>
               </sit1:Document>
            </sit:Documents>
            <sit:PropertyType>?</sit:PropertyType>
            <!--Optional:-->
            <sit:System>?</sit:System>
         </tem:request>
      </tem:CreateInsuranceContract>
   </soapenv:Body>
</soapenv:Envelope>

Не обязательно, что вам придется постоянно работать с XML, возможно вы будите использовать какой-то клиент или SDK для работы с WSDL, который поднимет вас на другой уровень абстракции, и вся работа будет сведена к передаче массива данных при вызове нужного метода, но понимание структуры и умение читать XML будет не лишним(я же на практике, предпочитаю комбинировать запросы сформированные таким клиентом и чистый XML, так я экономлю время на интеграции во взаимодействии с базовыми методами и получаю гибкость в интеграции со сложными многоуровневыми методами).

С WSDL вроде немного разобрались, теперь давайте перейдем дальше.

SOAP

Если WSDL это язык основанный на XML, то SOAP(от англ. Simple Object Access Protocol) это простой протокол доступа к объектам(работающий поверх сетевого протокола HTTP/HTTPS), предназначенный для обмена сообщениями между распределенными сервисами, как например в моем случае интегрируемая платформа и API страховой компании(вообще сервисы могут быть любые другие). Протокол SOAP работает с XML сообщениями, и так как WSDL это и есть XML сообщения, то SOAP для их передачи подходит как нельзя кстати. Таким образом, мы можем взять любой SOAP клиент, например в PHP есть стандартная клиентская-библиотека SoapClient, подключиться с помощью неё к WSDL серверу и начать обмениваться XML сообщениями. Более того, данный клиент на PHP имеет встроенную поддержку работы с WSDL, а это значить е него есть возможность получить инструкции от WSDL сервера, о том как и какие запросы слать.

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

Теперь давайте перейдем к WSDL серверу(предполагается что ссылка на него у вас уже есть, а если нет, то можете поэкспериментировать с тестовым) и посмотрим, какие у него есть методы(команды), с какими параметрами, что мы можем ему отправлять и что ожидать в ответ.

SoapUI

Поговорим о приложении(про которое я упоминал ранее) — SoapUI, которое позволяет тестировать веб-сервисы сервис-ориентированных архитектур, а именно их взаимодействие, работу протоколов, передачу сообщений, состояний REST, проверку веб-служб, запуск, разработку, моделирование и макетирование, функциональное тестирование, тестирование нагрузки и соответствия. В общем инструмент очень мощный, кроссплатформенный, бесплатный(не путать с его платной версий ReadyAPI), существующий с 2005 года и за минувшее время очень сильно доработанный и протестированный большим сообществом пользователей.

Для чего нам это приложение(программа)? С помощью него, мы подключимся к WSDL серверу, получим от него описание методов и свойств, сгенерируем документацию, а затем начнем тестировать взаимодействие с сервисом, формируя и отправляя WSDL сообщения(на языке XML) по протоколу SOAP. SoapUI позволяет очень быстро приступить к работе с методами WSDL сервера API(вашего сервиса), и после того когда вы все протестируете, составите корректные XML сообщения, все это можно будет перенести в код вашего проекта(например на PHP с использованием клиент SoapClient/Nusoap).

Далее давайте создадим проект в SoapUI и поработаем с WSDL.

1. Скачайте, установите и запустите SoapUI;
2. Создайте свой первый SOAP проект, указав WSDL сервер;
2.1 В окне приложения SoapUI, в панели навигации, во вкладке File, выберите пункт NEW SOAP Project;
Создание WSDL проекта
2.2 В открывшемся диалоговом окне, укажите название проект и нажмите Ок;
Добавление WSDL сервера
2.3 После чего новый проект будет создан и вы увидите его в левом окне приложения;
Новый проект
2.4 Добавляем WSDL сервер. Кликаем правой кнопкой мыши на свой проект и выбираем пункт Add WSDL.
Добавление WSDL
2.5 В открывшемся диалоговом окне, укажите URL WSDL сервера и нажмите Ок;
Диалоговое окно
2.6 После чего SoapUI, скачает с сервера WSDL всю информацию о взаимодействии с ним и построит список доступных методов.
Методы WSDL
3. Давайте построим документацию средствами SoapUI на основе WSDL. Для этого, кликните правой кнопкой мыши на проект и выберите пункт Generate Documentation, укажите папку для сохранения, после чего будет создан HTML документ с описанием всех методов, свойств и типов для взаимодействия с сервисом.
4. Протестируем метод взаимодействия с сервисом. Для этого кликнем по методу два раза, после чего откроется окно для его тестирования, с отображением шагов запросов, кликаем по первому и видим его XML код.
XML код WSDL
4.1 Далее в XML код, подставляем нужные нам данные для запроса, еще раз прописываем URL для запроса к WSDL серверу, если нужно добавляем авторизацию(например Basic Auth).
Авторизация WSDL basic Auth
4.2 Отправляем запрос, получаем и смотрим ответ, если нужно то корректируем параметры запроса, если все хорошо, то XML запроса можно переносить в наш PHP(например) проект.

И так, мы рассмотрели базовый функционал приложения SoapUI, теперь мы можем приступить к тестированию и отладке запросов к WSDL серверу. Когда все будет отлажено, можно переходить к коду проекту на PHP(в моем случае), где мы будем использовать не стандартный SoapClient(который весьма неплох), а отдельный класс PHP Client Nusoap.

PHP Client Nusoap

Зачем нам отдельный класс Nusoap для взаимодействия с протоколом SOAP, если в PHP уже есть стандартный SoapClient, спросите вы? Все очень просто, Nusoap имеет ряд готовых методов, таких как авторизация или подготовка и отправка XML сообщений, которые несколько проще в использовании чем аналогичные в SoapClient. Также, на практике, я встречал несколько хостингов где в списке расширений PHP не было SOAP, следовательно стандартный SoapClient не работал. Поэтому рассмотрим, простой пример работы с SOAP и WSDL используя Nusoap.

Подключение к серверу WSDL с авторизацией Basic auth:

	$client = new nusoap_client('https://адрес_сервера.ру', true); // Сервер
	$client->setCredentials('login', 'password', 'basic'); // Авторизация
	$client->soap_defencoding = 'UTF-8'; // Кодировка запроса
	$client->decode_utf8 = false; // Кодировка ответа

Отправка XML сообщения запроса:

	$soapaction = 'https://адрес_сервера.ру/название_метода/';
	$request_xml = ''; // XML код запроса
	$result = $client->send($request_xml, $soapaction, ''); // Отправка запроса

Вывод результата ответа в виде массива, сохраненного в переменную $result:

if ($client->fault) {
	echo '<h2>Ошибка. Ответ содержит неверное тело SOAP сообщения.</h2>'; print_r($result);
} else {
	$err = $client->getError();
	if ($err) {
		echo '<h2>Ошибка</h2>' . $err;
	} else {
		echo '<h2>Результат</h2>'; print_r($result);
	}
}
echo '<h2>Запрос</h2>' . htmlspecialchars($client->request, ENT_QUOTES);
echo '<h2>Ответ</h2>' . htmlspecialchars($client->response, ENT_QUOTES);
echo '<h2>Отладка</h2>' . htmlspecialchars($client->getDebug(), ENT_QUOTES);

Заключение

Освоив этот базовый набор знаний о XML, SOAP и инструментов для работы с WSDL далее вы очень быстро освоите и другие особенности взаимодействия распределенных сервисов использующих этот стек технологий. К сожалению, когда я начинал работу над своей первой интеграцией, мне не удалось найти статью по WSDL описывающую именно быстрый старт в изучении методов и внедрения алгоритмов работы с ними в код проекта на PHP(в основном встречается множество разрозненной информации по каждому описанному мною пункту отдельно). Надеюсь моя статья-заметка будет полезна вам!

Если вам нужна помощь в интеграции вашего проекта по API с каким либо сервисом использующего WSDL — обращайтесь, буду рад сотрудничеству с вами!

Оставить комментарий

Автор блога
Чернышов Роман
Роман Чернышов
Веб-разработчик, Full Stack
Senior, Architector
PHP, JavaScript, Node.JS, Python, HTML 5, CSS 3, MySQL, Bash, Linux Admin
Заказать работу
предложить оффер

Последние вопросы
Список вопросов
Последние комментарии
Меню

Archive

Мои проекты
Insurance CMS Love Crm CMS Совместные покупки Мой PHP Framework Хостинг для моих клиентов Лицензии на мой софт и поддержка