Консалтинг и автоматизация в области управления
эффективностью банковского бизнеса

Журнал ВРМ World

"Мыльный" SOAP

В предыдущей статье мы дали определение Web-службе. Теперь самое время перейти к изучению одного из основных протоколов, с помощью которых строятся службы, а именно протокола SOAP (Simple Object Access Protocol). Первоначальная спецификация SOAP версии 0.9, было опубликована в сентябре 1999 года, после чего, претерпев две редакции, вышла в свет в декабре 1999 года как версия 1.1. SOAP 1.1 фактически стал стандартом, он признан большинством поставщиков программного обеспечения и широко используется в реализациях клиент- сервер. Спецификация определяет ряд соглашений по обмену XML-сообщениями, в том числе правила по кодированию структур данных, алгоритм расширяемости, присоединение к HTTP-протоколу, требования к вызовам типа RPC (Remote Procedure Call, Удаленный вызов процедуры). Международный консорциум W3C (World Wide Web Consortium) намерен добиться того, чтобы SOAP был придан статус Рекомендации W3C - этим вопросов занимается Рабочая группа протокола XML (XML Protocol Working Group). В настоящий момент группа работает над SOAP 1.2, используя в качестве отправной точки SOAP 1.1; в спецификацию вносятся некоторые изменения и уточнения.

Прежде чем продолжить разговор о SOAP, давайте зададимся простым вопросом: а зачем нам вообще нужен протокол, например, SOAP? Другими словами, что нам даст SOAP? Если две стороны используют Web-службу для обмена информацией, записанной в виде XML, что может помешать им договориться о словаре и структуре XML и определить свой собственный протокол? Тогда каждая пара участников обмена неизбежно создаст свой собственный, специфический протокол. Таким образом, если n - это число участников обмена, то потенциально число протоколов может достичь n-1 включительно. Хотя реализация одного протокола не представляет особых трудностей, при увеличении n, например при n > 6, бремя внедрения становится весьма ощутимым. Наличие одного стандартного протокола приносит единообразие в определенных аспектах коммуникации и, следовательно, существенно снижает сложности реализации. В результате, появляется возможность устанавливать средства обработки в другие приложения, например, серверные продукты, клиентские продукты, операционные системы. В этом случае отдел внедрения Web-службы (или же клиенты этой службы) сможет сконцентрироваться на специфических задачах данной службы, а не на общих вопросах, характерных для всех Web-служб.

Распознавание сообщения

SOAP определяет внешний элемент для всех SOAP-сообщений, которыми обмениваются Web-служба и ее клиент. Подобно тому, как элемент stylesheet в пространстве имен XSLT сообщает XSLT-процессору, что в действительности это XML - преобразование, элемент Envelope в SOAP пространстве имен показывает SOAP-процессору, что это XML - SOAP-сообщение. Тогда процессор сможет искать индивидуальную часть сообщения: обязательный элемент Body, который содержит действительный запрос, и факультативный элемент Header, который содержит элементы расширения. Ниже показан скелет SOAP-сообщения:

soap:Envelope xmlns:soap=
'http://www.w3.org/2001/10/soap-envelope'>
 <soap:Header>

  <-- Headers go here -->

 </soap:Header>
 <soap:Body>

  <-- Request goes here -->

 </soap:Body>
</soap:Envelope>

Заголовки (Header) и расширяемость

Элемент Header обеспечивает в SOAP механизм расширяемости. Этот элемент может содержать любое число квалифицированных дочерних элементов пространства имен. Каждый из этих элементов - некая разновидность расширения в базовом SOAP-протоколе. Скажем, один элемент может содержать данные, связанные с управлением диалогом или сессией между клиентом и сервером. Другой может содержать информацию об аутентификации или даже сведения о текущей транзакции. С другой стороны он может содержать и локальную информацию. Каково бы ни было их содержание или семантика, каждый элемент header некоторым образом модифицирует SOAP-протокол, обеспечивая дополнительный контекст для обработки тела сообщения. Для клиента имеет огромное значение, что сервер принимает на обработку некоторые расширения; классический пример - аутентификация. Другие расширения, такие как локальная информация, могут быть менее критичными. Каждый заголовочный элемент (header) может быть снабжен комментариями с помощью атрибута mustUnderstand. Если этот атрибут имеет значение true или 1, то заголовок считается обязательным. Если получатель сообщения не распознает заголовок или не понимает его, он должен генерировать SOAP-сообщение об ошибке. Заголовки без атрибута mustUnderstand (или же если mustUnderstand имеет значение false или 0) считаются факультативными. Получателю таких заголовков не требуется их обрабатывать. Ниже приведен пример SOAP-сообщения, содержащий одно обязательное и одно факультативное расширение:

<soap:Envelope xmlns:soap=
'http://www.w3.org/2001/10/soap-envelope'>
 <soap:Header>
  <h:Log xmlns:h=
  'http://example.org/cvs/logging'>
    <trace>4</trace>
  </h:Log>
  <h:PServer xmlns:h=
    'http://example.org/cvs/pserver'
    soap:mustUnderstand='true' >
   <username>anoncvs@example.org</username>
   <password>anoncvs</password>
  </h:PServer>
 </soap:Header>
 <soap:Body>
  <m:Checkout xmlns:m=
    'http://example.org/cvs'>
   <source>/xml/soap/webservices/cvs</source>
   <revision>1.1</revision>
   <destination>/etc/usr/marting/source/xml
   </destination>
  </m:Checkout>
 </soap:Body>
</soap:Envelope>

Модель расширяемости обеспечивает стандартное размещение расширений протокола, а также стандартный механизм обозначения расширений как обязательных. Повторимся: этот подход упрощает внедрение приложений или кода, используемого для обработки расширений на уровне инфраструктуры.

Заголовки и модель обработки SOAP

При простом обмене "клиент-сервер" используется обыкновенная модель обработки сообщений, не содержащих заголовки. Обычно сервер распознает содержание элемента Body как запрос на предоставление некой услуги. Сервер выполняет эту работу и может факультативно отправить ответ обратно. Если же он не распознает содержание элемента Body, или в процессе обработки возникают какие-либо иные ошибки, сервер генерирует SOAP-сообщение об ошибке, в котором описан характер погрешности.

Заголовочные элементы в некоторой степени усложняют эту модель обработки, что создало почву для долгих споров о многих аспектах обработки заголовков. Например, значение атрибута mustUnderstand (букв. должен понимать). Что значит "понимать" отдельно взятый атрибут? И если данный процессор понимает заголовок, требуется ли обрабатывать его? В результате был предложен дополнительный атрибут mustProcess. При его задании получатель должен был бы не только понимать заголовок, но и обрабатывать его. Подобным образом можно было бы ужесточить определение атрибута mustUnderstand (что и предлагается в черновом варианте SOAP 2.1), потребовав, чтобы обязательные заголовки обрабатывались в соответствии со спецификацией для заголовка, или чтобы SOAP-процессор генерировал сообщение об ошибке. Помимо этого, процессор для SOAP 1.2, прежде чем приступить к обработке любой части сообщения, должен гарантировать, что он понимает все обязательные заголовки в данном сообщении, включая содержание элемента Body. В результате, модель обработки несколько проясняется, однако ситуация усложняется при реализации потоков, которые, возможно, будут пытаться обработать заголовки всякий раз, как только с ними столкнутся. Если заголовков обрабатываются подобным образом, должна быть гарантия того, что будет возможен "откат" результатов обработки заголовков, если затем обязательный заголовок не понимается SOAP-процессором.

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

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

В настоящий момент описано всего несколько заголовков, и не один из них не является стандартным. Со временем различные участники этого сектора экономики дадут свое определение. Некоторые заголовки станут стандартом и будут опираться на многочисленные реализации, другие исчезнут в небытие. Важно, что стандартные заголовки хорошо определены и не нарушают работу базового протокола. Стоит также заметить, что некоторые службы, например, Biztalk Server, используют фирменные заголовки. И хотя, строго говоря, эти Web-службы подчиняются спецификации SOAP, они не могут взаимодействовать с клиентами (или другими службами), которые не понимают эти нестандартные заголовки. Остается посоветовать как разработчикам, которые планируют стать клиентами Web-служб, равно как всем, кто будет внедрять эти службы, хорошенько подумать о том, какие заголовки, если они, конечно, их заинтересуют, они готовы использовать.