Что такое web служба

Что такое web служба

Индекс материала
Что такое web служба
Описание с помощью WSDL
Создание Web-служб
Все страницы

Основной концепцией Web-служб является обмен данными между компьютерами с помощью стандартизированных протоколов и сообщений. Эта идея далеко не нова. Тем не менее, за последние пару лет гиганты рынка собрались вместе, и слава богу, определили несколько основополагающих стандартов. Результатом этого стало то, что теперь возможно "говорить" с другими системами или компьютерами без вмешательства человека или без глубоких познаний того, как устроена Web-служба на другой стороне. Вы просто читаете стандарты и следуете им. Итак, Архитектура SOA - архитектура, ориентированная на службы - эта "умная фраза" очень хорошо объясняет роли, присущие приложению, ориентированному на Web-службы. Всего в нем имеется три участника;

  • Поставщик.
  • Потребитель.
  • Справочник UDDI.

Потребитель ищет услугу в справочнике, а поставщик публикует информацию об услуге в этом справочнике. Затем потребитель может запросить информацию у поставщика, который (хочется верить) с удовольствием выполнит просьбу. Наглядно эти взаимоотношения показаны на рисунке ниже. Для обмена информацией между этими тремя участниками системы SOA необходимы стандарты для решения следующих трех задач:

  • Передача сообщений.
  • Описание.
  • Поиск в справочнике UDDI.

soa

Передача сообщений с помощью SOAP

Передача сообщений обычно осуществляется с помощью протокола HTTP, потому что брандмауэры, как правило, пропускают HTTP-трафик, хотя некоторые производители аппаратных брандмауэров уже начали вносить в свои системы изменения, которые позволяют фильтровать нежелательные запросы Web-служб. Впрочем, следует отметить, что HTTP — не единственно возможный транспортный протокол. Кроме него еще используется (правда очень редко) протокол SMTP.

Протокол SOAP инкапсулирован в HTTP. Когда-то SOAP расшифровывался как Simple Object Access Protocol (простой протокол доступа к объектам). Однако с этим названием возникло две проблемы: во-первых, протокол SOAP отнюдь не простой, а во-вторых, он не имеет ничего общего с доступом к объектам. Поэтому, начиная с версии 1.2, SOAP обозначает ... SOAP ("мыло") и больше ничего.

SOAP

Спецификация SOAP 1,1 была разработана совместными усилиями компаний Microsoft, Compaq, HP, IBM и SAP и в апреле 2000 года передана консорциуму W3C. В консорциуме W3C этим стандартом занималась рабочая группа по протоколу XML (XML Protocol Working Group). Они разработали версию 1.2, которая с июня 2003 года является рекомендацией W3C. В настоящее время SOAP-расширеиие для РНР 5 поддерживает большую часть спецификаций SOAP 1.1 и 1.2.

Кстати!

Возможно, вы слышали об XML-RPC. Пока компания Microsoft разрабатывала то, что впоследствии стало протоколом SOAP, один из участников команды, Дэйв Вайнер (Dave Winer) из UserLand, Inc., был разочарован общим ходом работ над стандартом и опубликовал то, что было сделано им к тому времени. Это и был XML-RPC.

SOAP Пакет

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


  <?xml version="1.0" encoding="UTF-8" ?>
  <SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemes.xmlsoap.org/soap/envelope/"
  xmlns:nsl="urn:php5unleashed-guid"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:SOAP-ENC="http://schemas.xjnlsoap.org/soap/encoding/"
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <SOAP-ENV:Body>
          <nsl:getGuid>
              <prefix xsi:type="xsd:string">PHP_</prefix>
          </nsl:getGuid>
      </SOAP-ENV:Body>
  </SOAP-ENV:Envelope>
  
Что здесь происходит? Вначале мы создаем SOAP конверт, который вызывает службу с указанием URN (Uniform Resource Name - унифицированного имени ресурса) phpSunleashed-guid. Затем вызывается метод getGuid с передачей ему параметра prefix со значением РНР_. SOAP-ответ этого вызова web-службы может выглядеть так, как показано ниже. Обратите внимание на возвращаемое значение — в данном случае: PHP_411f663ce6ce5.

  <?xml version="1.0" encoding="UTF-8" ?>
  <SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/scap/envelope/"
  xmlns:nsl="urniphpSunleashed-guid"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:SOAP-ENC="http'. //schemas-xmlsoap.org/soap/encoding/"
  SOAP-ENV:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/">
      <SOAP-ENV:Body>
          <nsl:getGuidResponse>
              <Result xsi:type="xsd:string">PHP_411f663ce6ce5</Result>
          </nsl:getGuidResponse>
      </SOAP-ENV:Body>
  </SOAP-ENV:Envelope>

Протокол SOAP позволяет выполнять намного большее, нежели просто возврат строк. Помимо всего прочего, он поддерживает пользовательские типы данных. Кроме того, вам совершенно не нужно беспокоиться об этом, поскольку о большей части технических деталей заботится PHP-модуль SOAP, который преобразовывает структуры данных SOAP в соответствующие структуры данных РНР.


Описание с помощью WSDL

SOAP работает очень хорошо, если о Web-службе все известно. Однако это не всегда так. Средством описания интерфейса для доступа к Web-службе является язык WSDL (Web Services Description Language — язык описания Web-служб). Этот стандарт совместно разработан компаниями IBM, Microsoft и webMethods. У каждой из этих трех компаний был собственный подход к разработке стандарта для описания Web-служб: IBM создала NASSL, Microsoft разработала SCL, а компания webMethods придумала WIDL.

Результатом их сотрудничества стала версия 1.1 языка WSDL, По поводу W3C следует отметить, что так же как и с SOAP, консорциум W3C на основе версии 1.1 разработал версию WSDL 1.2, которая теперь является рекомендацией W3C. WSDL-описание Web-службы содержит всю необходимую для использования этой службы информацию, включая доступные методы и их параметры. Эта информация содержится в следующих пяти элементах:

  • <binding> - поддерживаемые протоколы.
  • <message> - сообщения Web-службы (запрос, ответ).
  • <portType> — все доступные методы.
  • <service> — URI службы.
  • <types> — используемые типы данных.

Вся эта информация хранится в корневом элементе WSDL-описания <deЈinitions>, В листинге ниже представлен пример WSDL-описания Web-службы.

WSDL-описание Web-службы


  <?xml version="1.0" encoding="UTF-8"?>
  <definitions name="Guid"
  targetNamespace="http://www.hauser-wenz.de/Guid/"
  xmlns:tns="http://www.hauser-wenz.de/Guid/"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
  xmlnsгwsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns="http://schemas.xmlsoap.org/wsdl/">
  
      <message name="getGuidResponse">
          <part name="Result" type="xsd:string" />
      </message>
      
      <message name="getGuidRequest">
          <part name="prefix" type="xsd:string" />
      </message>
      
      <portType name="GuidPortType">
          <operation name="getGuid" parameterOrder="prefix">
              <input message="tns:getGuidRequest"/>
              <output message="tns:getGuidResponse" />
          </operation>
      </portType>
      
      <binding name="GuidEinding" type="tns:GuidPortType">
      
          <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
          
          <operation name="getGuid">
          
              <soap:ореration soapAction="urn:php5unleashed-guid#getGuid"/>
              
              <input>
                  <soap:body use="encoded" namespace="urn:php5unleashed-guid"
                  encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" />
              </input>
              
              <output>
                  <soap:body use="encoded" namespace="urn:php5unleashed-guid"
                  encodingstуle="http://schemas.xmlsoap.org/soap/encoding/" />
              </output>
              
          </operation>
          
      </binding>
      
      <service name="GuidService"
          <port name="GuidPort" binding="tns:GuidBinding">
              <soap:address location="http://localhost/php/guid-server.php"/>
          </port>
      </service>
      
  </definitions>

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

Кстати!

Для автоматического создания WSDL-описания вы можете использовать альтернативные реализации протокола SOAP в РНР:

Поиск в справочнике с помощью UDDI

Теперь, после того как мы знаем, как получать информацию о Web-службе и как ее запрашивать, нужно научиться находить такую службу. Для этой цели существует нечто похожее на "Желтые страницы", а именно — реестры UBR (Universal Business Registries - универсальные бизнес-реестры) - справочники Web-служб.

Существует несколько таких реестров, среди которых реестры компаний IBM, Microsoft, NTT-Com и SAP. Эти реестры синхронизируют свои данные, поэтому можно пользоваться любым из них. Текущей версией стандарта UDDI является версия UDDI 3.0, хотя большинство реализаций используют версию 2. Среди разработчиков этого стандарта такие компании-гиганты, как HP, Intel, Microsoft и Sun.

Для взаимодействия с UBR существует два типа API-интерфейсов: Inquiry API и Publish API. Интерфейс Inquiry API (Запрос) предназначен для запроса служб в реестрах UBR, а интерфейс Publish API (Публикация) позволяет разработчикам регистрировать свои службы. Похоже, что заполнение содержимого реестров спамом — это только вопрос времени :)

Кстати!

Существуют тестовые реестры, предназначенные для тестирования регистрации служб перед их размещением в "настоящих" реестрах.

Так выглядит запрос Web-службы:


<?xml version="l.0" encoding="utf-8"?>
<Envelope xmlns="http://scheinas.xinlsoap,org/soap/envelope/">
<Body>

    <find_business maxRows="25" xmlns="urn:uddi-org:api_v2" generic="2.0">

        <findQualifiers>
            <findQualifier>sortByNameAsc</findQualifier>
            <findQualifier>sortByDateDesc</findQualifier>
        </findQualifiers>

        <name>%guid%</name>

    </find_business>
    
</Body>
</Envelope>

В примере выше видно, что UDDI-запрос инкапсулирован в SOAP-сообщение, поэтому выглядит он довольно знакомым. Ответом на запрос является также SOAP-документ, показанный ниже:


  <?xml version="1.0" encoding="UTF-8" ?>
  <SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP:Body>
  
  <businessList generic="2.0" xmlns="urn:uddi-org:api_v2" operator="www.ibm.com/services/uddi" truncated="false">
      <businessInfos>
          <businessInfo businessKey="DEFBD260-4CD5-llDe-B936-000629DCQA53">
          
              <name xml:lang="en">Web Services Guided Tour</name>
  
              <description xml:lang="en">Sample Web services for Guided Tourbook</description>
  
              <serviceInfos>
                  <serviceInfo serviceKey="2A839AS0-4CEl-llDS-B936-O0Q629DC0A53" businessKey="DEFBD2e0-4CD5-llDB-B936-00O629DC0A53">
                      <name xml:lang="en">Guided Tour StockQuote Service</name>
                  </serviceInfo>
              </serviceInfos>
              
          </businessInfo>
      </businessInfos>
  </businessList>
  
  </SOAP:Body>
  </SOAP:Envelope>

Установка

Установить SOAP-расширение для PHP5 довольно легко. В Windows этот модуль находится в подкаталоге ext каталога установки РНР. Для его использования необходимо в файл php.ini добавить следующую строку: extension=php_soap.dll Для работы этому модулю требуется , которая включена в РНР 5 по умолчанию, по крайней мере, в Windows-версии.

В Unix/Linux/Mac потребуется установить библиотеку libxml версии не ниже 2.5.4 Кроме того, при конфигурировании РНР необходимо указать ключ --enable-soap


Создание Web-служб

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

В самом конце WSDL описания (приведённого на предыдущей странице) находится URL-адрес Web-службы:
<soap:address location="http://localhost/php/guid-server.php" /> - Замените этот URL на адрес вашей службы. После того как описание создано, можно приступать к написанию самой службы.

Итак, создаваемая нами Web-служба будет возвращать GUID (Globally Unique Identifier — глобально уникальный идентификатор) с префиксом, передаваемым службе в качестве параметра. Как известно, в РНР для этой цели существует функция uniqid(), В действительности наша Web-служба является оболочкой для uniqid(). Функция getGuid () выглядит следующим образом:


  function getGuid($prefix)
  {
    return uniqid($prefix);
  }

Осталось сделать всего три шага - или строки кода:
  1. Создать SOAP-сервер, указав WSDL-описание.

  2. Добавить к серверу функцию getGuid ().

  3. Поручить серверу обработку всего остального.

Внимание!

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

Запретить кэширование можно также и в конкретном PHP-сценарии с помощью функции ini_set():


  ini_set('soap.wsdl_cache_enabled',  'Off');

Листинг ниже содержит завершенный ход этого примера, включая запрет на кэширование WSDL.


ini_set('soap.wsdl_cache_enabled',  'Off');

function getGuid(Sprefix)
{
	return uniqidtSprefix);
}

$soap = new SoapServer('guid.wsdl');

$soap->addFunction('getGuid');

$soap->handle();

Использование Web-служб

Сама по себе служба не покажет в Web-браузере ничего полезного. Если просто набрать её адрес то как показано в листинге ниже, мы получим сообщение об ошибке. Причина очевидна: мы вызвали Web-службу, но не передали ей SOAP-запрос, поэтому она справедливо жалуется на "неправильный запрос" (Bad Request):

  <?xml version="1.0" encodings "UTF-8" ?>
  <SOAP-ENV:Envelope xmlns:SOAP-ENV="ltttp://schemas.xmlsoap.org/soaр/envelope/ ">

      <SOAP-ENV:Body>

          <SOAP-ENV:Fault>
              <faultcode>SOAP-ENV:Server</faultcode>
              <faultstring>Bad Request. Can't find HTTP_RAW_POST_DATA</faultstring>
          </SOAP-ENV:Fault>

      </SOAP-ENV:Body>

  </SOAP-ENV:Envelope>

Чтобы использовать эту службу (и получить желанный GUID) нам потребуется клиент. Для решения этой задачи расширение SOAP для РНР 5 предлагает простой способ доступа к Web-службе при условии доступности ее WSDL-oписания. Конструктор класса SoapClient принимает в качестве аргумента имя файла с WSDL-описаниеми создает прокси-объект. Поведение этого локального объекта точно такое же, как и удаленной службы.

Преимущество такого подхода заключается в том, что вы можете работать со службой как с локальным объектом, не заботясь о таких вещах, как открытие соединения, создание и синтаксический разбор SOАР-документа и тому подобное. По существу запрос к Web-службе сводится к двум строкам кода. В листинге ниже добавлена еще одна строка, запрещающая WSDL-кэширование.


  ini_set('soap.wsdl_cache_enabled', 'Off');
  $soap = new SoapClient('guid.wsdl');
  echo $soap->getGuid('PHP_');

Результатом будет строка: PHP_411f663ce6ce5

Однако этот класс содержит намного больше возможностей. Одной из них является обработка ошибок. Например, может потребоваться, чтобы передаваемый префикс имел непустое значение и не был пустой строкой или строкой, содержащей лишь пробельные символы. Если эти условия не соблюдены, должно возвращаться сообщение об ошибке. Для этих целей воспользуемся встроенным объектом SoapFault, предназначенным для обработки ошибок SOAP. В листинге шиже показан обновленный сервер нашей Web-службы, на этот раз возвращающей еще и сообщение об ошибке.


  ini_set('soap.wsdl_cache_enabled', 'off');
  
  function getGuid($prefix)
  {
    //Если не указан префикс...
    if(!isset($prefix) || trim($prefix) == '')
    { 
      //SOAP-сервер возвращает сообщение об ошибке:
      throw new SoapFault('Server',  'He указан префикс.');
    }
    else
    {
      return uniqid($prefix);
    }
  }
  
  $soap = new SoapServer{'guid.wsdl') ;
  $soap->addFunction('getGuid');
  $soap->handle();

Пример ниже содержит обновленный код клиента, который теперь с помощью конструкции try...catch проверяет возвращаемый ответ на наличие ошибок.

SOAP-клиент с обработкой ошибок:


ini_set('soap.wsdl_cache_enabled', 'Off');

$soap = new SoapClient('guid.wsdl');

try
{
	echo $soap->getGuid('PHP_');
}
catch(SoapFault $e)
{
	echo $e->faultstring;
}

Если заменить вызов getGuid ('РНР_') на getGuid( ), то SOAP-сервер вернет сообщение об ошибке: "He указан префикс."

Итак мы узнали, как работать с Web-службами с помощью расширения SOAP для РНР 5. Хотя базовые технологии, такие как SOAP и WSDL. являются сами по себе довольно сложными, пользоваться ими в РНР довольно просто. За исключением подготовки WSDL-описаний, вся остальная работа сводится к написанию нескольких строк PHP-кода.

Для получения дополнительной информации обратитесь к описанию упоминаемых в этой статье стандартов:


Добавить комментарий


Защитный код
Обновить



Кто на сайте
Сейчас 135 гостей онлайн