среда, декабря 06, 2006

Проектирование web сервисов

В данной статье мне хотелось бы обсудить вопросы, связанные с проектированием web сервисов, предназначенных для межпрограммного взаимодействия. Так называемых – интеграционных web сервисов. Прежде всего, это сервисы, которым предстоит работать в различных решениях класса Enterprise Applications Integration (EAI), а также в B2B решениях. Вопросам разработки web сервисов с использованием различных платформ посвящено множество книг и статей, а вот вопросы проектирования освещены гораздо хуже. Вы можете найти массу статей с заклинаниями на тему SOA, которые будут совершенно бесполезны, когда вы приступите к проектированию своего web сервиса.
Итак, давайте рассмотрим ситуацию, когда у вас на руках есть две работающие системы (либо проекты двух систем), и перед вами стоит задача организовать взаимодействие между ними. Вам надоели схемы синхронизации на основе файлов импорта / экспорта, и вы остановили свой выбор на модной, современной и удобной технологии web сервисов. Я попытаюсь рассказать о том, на что следует обратить внимание и как избежать типичных ошибок при проектировании web сервиса для взаимодействия двух систем.

Немного SOA


И все же, сначала пару слов о небезызвестной SOA. Термин Service Oriented Architecture (SOA) довольно серьезно пострадал от беспорядочного употребления в маркетинговых целях. Его так часто употребляют в различных контекстах, что теперь сказать что-то определенное о SOA, кроме того, что это - «сервис ориентированная архитектура», уже трудно.
Тем не менее, SOA имеет такое же право на жизнь, как и «клиент – серверная архитектура» или «много уровневая архитектура». Как и любая другая «архитектура», SOA вводит ряд абстракций и правил, которые помогают нам в разработке определенного класса приложений. В данном конкретном случае, руководствоваться принципами SOA полезно при разработке механизмов взаимодействия и интеграции приложений в масштабе предприятия (Enterprise Applications Integration - EAI).
Итак, начнем с того, что SOA рассматривает приложения как сервисы или совокупности сервисов, которые обмениваются сообщениями напрямую, либо посредством некоторых интеграционных механизмов. Эти сервисы должны удовлетворять ряду условий или требований.
Во-первых, сервис должен иметь определенное «business value», иными словами, сервис должен иметь прикладное значение. Если вы не можете простыми словами объяснить заказчику или пользователю системы для чего нужен ваш сервис, то с точки зрения SOA это неудачный сервис. Пример плохого сервиса: «Сервис для получения глобально – уникальных идентификаторов». Пример хороших сервисов: «Сервис данных о сотрудниках предприятия» или «Сервис приема и обработки счетов к оплате» (Accounts Payable).
Во-вторых, с точки зрения SOA, сервисы должны быть автономными и независимыми. Это необходимо для того, чтобы как это принято в SOA, мы могли комбинировать одни сервисы с другими в зависимости от потребностей бизнеса. Если мы захотели использовать «Сервис приема и обработки счетов к оплате» и при этом узнаем, что нам придется установить и использовать «Сервис бюджетирования и финансового планирования», «Сервис ведения главной книги», и еще дюжину сервисов, то с точки зрения SOA все это выглядит просто отвратительно.
В-третьих, сервис должен быть функционально полным с прикладной точки зрения. Это требование комплиментарно предыдущему. Например, «Сервис приема и обработки счетов к оплате» позволяет добавить заявку, а отследить ее статус не позволяет. Но в принципе мы можем получить отчет по заявкам, из которого можно узнать о статусе заявки. Не правда ли, знакомая ситуация? С точки зрения SOA, да и с любой точки зрения – это не правильно. Сервис должен обеспечивать выполнение всех основных бизнес операций, связанных с прикладной областью или бизнес процессом, который он обеспечивает.
В-четвертых, все сервисы должны уметь предоставлять свои описания в некотором стандартизированном формате. WSDL и UDDI - это варианты форматов описания сервисов.
В-пятых, сервисы должны быть ориентированы на распределенное асинхронное взаимодействие без хранения состояния. Это типично для большинства современных распределенных систем, и это очень важное требование. Достаточно вспомнить, что клиент-серверная архитектура ориентирована на синхронное взаимодействие с хранением состояния, и именно это обстоятельство стало ключевым ограничением для дальнейшего развития этой архитектуры.
В-шестых, SOA предполагает, что благодаря выполнению предыдущих требований, сервисы будут способны объединяться для взаимодействия друг с другом при помощи различных интеграционных инструментов, типа брокеров и маршрутизаторов сообщений, серверов workflow и т.д. и т.п. Ключевым моментом здесь является тот факт, что интеграционные сценарии будут основываться на конфигурировании, часто визуальном, а не на разработке специального «интегрирующего» кода, как это делается в большинстве случаев сейчас.
Вот примерно так выглядят основные вехи, на которые мы должны ориентироваться и которые должны ограничивать нашу разыгравшуюся дизайнерскую мысль в процессе проектирования и разработки интеграционных web сервисов.

Проектирование контракта сервиса.


После того, как Microsoft в своей платформе Windows Communication Foundation – WCF (бывшая Indigo) использовала термин «контракт сервиса», он имеет все шансы сделаться стандартным термином де-факто.
Контракт сервиса - это описание сигнатур всех его операций (методов), плюс описание форматов данных, которыми он оперирует в качестве входных и выходных сообщений.
Для web сервисов контракт исчерпывающе описывается WSDL схемой сервиса. Однако согласитесь, что WSDL не очень хорошо приспособлен для человеческого восприятия. Гораздо нагляднее контракт можно изобразить в виде UML диаграммы классов. К счастью, большинство современных платформ для разработки web сервисов обеспечивают функцию автоматической генерации WSDL описания сервисов.
Правильно спроектированный контракт сервиса, залог успеха, и гарантия того, что ваш сервис проживет долгую и счастливую жизнь, и умрет своей смертью, потому что на смену ему придет новая технология, о которой мы сейчас ничего не знаем.
Microsoft предлагает специальный термин – “contract first” для описания подхода к проектированию, ориентированного в первую очередь, на контракт. Он предполагает, что проектирование сервиса должно начинаться с описания XSD схем сообщений (данных), затем создается WSDL описание операций сервиса, по которому генерируется код класса сервиса. И лишь после этого приступают к имплементации логики. Идея здравая, однако, я повторюсь, что работать с XSD и WSDL не очень удобно, даже с использованием визуальных средств типа XmlSpy. Кроме того, сам по себе принцип “contact first” не гарантирует нам получения правильного контракта сервиса.
Для меня принцип “contact first” означает, что при проектировании сервиса мы должны в первую очередь думать о его контракте и в последнюю - о деталях реализации. Следует взглянуть на будущий сервис c внешней стороны, глазами потребителя данных этого сервиса. Такой взгляд упрощает транспонирование требований предъявляемых к сервису в набор предоставляемых им операций. Например, мы разрабатываем сервис, предоставляющий данные о сотрудниках предприятия. Логично предусмотреть в нем операцию, возвращающую список всех сотрудников. Однако, в ходе анализа требований может оказаться, что потребителю данных нашего сервиса будет интересен, в первую очередь, список сотрудников конкретного подразделения. Это говорит нам о том, что в контракт операции, возвращающей список сотрудников, следует добавить параметр, позволяющий отфильтровать сотрудников конкретного подразделения, либо, нам следует выделить это действие в отдельную операцию сервиса. Такой подход будет соответствовать принципу “contract first”. И напротив, мы могли бы возложить на потребителя данных нашего сервиса обязанность выбрать сотрудников нужного ему отдела из общего списка. Придерживаться подобной стратегии при проектировании интеграционных сервисов – плохая практика. Разбирая конкретный данный случай, мы можем говорить о том, что такое решение не оптимально с точки зрения нагрузки на сервис или объема трафика, а также что такое решение снижает безопасность. Обобщая, можно сказать, что основания простоты и универсальности не должны превалировать при проектировании сервиса. Универсальность сервиса должна достигаться тщательным дизайном. Крайне сложно дать какие либо практические рекомендации в данном направлении. Не легко создать сервис, который бы не состоял из одного метода, вываливающего все внутренние данные системы наружу, и в тоже время был достаточно универсальным для того, чтобы его смог использовать не только тот потребитель, для которого вы проектировали сервис, но и любой другой. Чтобы добиться этого, следует обращать внимание на функциональную полноту контракта сервиса.
Давайте рассмотрим пример. Предположим, существует некая система учета и согласования счетов к оплате, из разряда тех, что обозначаются термином Accounts Payable. Система позволяет вводить данные счетов к оплате, обеспечивает бизнес процесс их согласования и, далее взаимодействует с бухгалтерской системой для формирования платежей. Ввод счетов и их согласование осуществляется, через UI системы. Перед нами стоит задача: создать web сервис, посредством которого другие системы могли создавать счета и отслеживать их статус.
Для простоты, будем считать, что счет к оплате имеет следующую структуру:

Где:
Number – уникальный номер счета, присваиваемый при создании
RecipientID – ссылка на справочник контрагентов, в котором хранятся все реквизиты получателя платежа
Amount – сумма к оплате
PaymentDate – дата оплаты
CategoryID – ссылка на справочник категорий платежей
Owner - имя сотрудника, который создал счет
Description – описание
State – состояния счета, вокруг которого строится бизнес процесс согласования счета.
Итак, исходные требования нам ясны. Схема данных для представления счета, тоже понятна. На основе представленной диаграммы будет создана вот такая XML схема, которая нас вполне устраивает:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
<xsd:complexType name="Payment">
<xsd:sequence>
<xsd:element minOccurs="1" maxOccurs="1" name="RecipientID" type="xsd:int" />
<xsd:element minOccurs="1" maxOccurs="1" name="Amount" type="xsd:decimal" />
<xsd:element minOccurs="1" maxOccurs="1" name="PaymentDate" type="xsd:dateTime" />
<xsd:element minOccurs="1" maxOccurs="1" name="CategoryID" type="xsd:int" />
<xsd:element minOccurs="0" maxOccurs="1" name="Owner" type="xsd:string" />
<xsd:element minOccurs="0" maxOccurs="1" name="Description" type="xsd:string" />
<xsd:element minOccurs="1" maxOccurs="1" name="State" type="tnxsd:PaymentState" />
</xsd:sequence>
<xsd:attribute name="Number" type="xsd:int" use="required" />
</xsd:complexType>
<xsd:simpleType name="PaymentState">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Draft" />
<xsd:enumeration value="Approved" />
<xsd:enumeration value="Rejected" />
<xsd:enumeration value="Commited" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema >



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

Выглядит просто ужасно! Давайте разберем, что здесь не так.
Метод добавления счета AddPayment() принимает в качестве параметра структуру Payment, а возвращает номер, присвоенный счету. Структура Payment не очень подходящий тип данных для параметра этого метода, потому что она содержит ряд полей, заполнение которых подчиняется внутренней бизнес логике системы. Это поля Number, State и Owner. Мы не знаем этих бизнес правил, и не знаем, как заполнять эти поля. Для создания счета мы должны указать: получателя, сумму платежа, дату, категорию и описание. Поэтому имеет смысл создать метод именно с такими параметрами, который создаст счет к оплате и вернет его в структуре Payment.
Метод ListPayments() возвращает список счетов в виде массива структур Payment. Возможно, система должна возвращать только те счета, которые были созданы данным пользователем. Однако отсутствие соответствующего параметра в сигнатуре метода не должно вас удивлять. Более надежный и безопасный способ получить данные о пользователе, - взять их из данных аутентификации. Со временем в системе может накопиться огромное количество счетов, и данному методу не помешали бы параметры для фильтрации выдаваемого списка по датам.
Наконец, метод RemovePayment() - принимает номер счета и возвращает true в случае успешного удаления и false в противном случае. Использование Boolean в качестве результата не лучшее решение в данном случае. Причины неудачи операции удаления могут быть самыми различными от простого отсутствия счета с указанным номером, до нарушения логических ограничений системы (например, нельзя удалить счет со статусом Commited). Ситуация довольно распространенная. Ошибка может случиться при выполнении любого метода web сервиса, и, к счастью, инфраструктура web сервисов предлагает стандартный подход к решению этой проблемы. Для передачи данных об ошибке используется SOAP сообщение, в теле которого содержится элемент Fault с информацией об ошибке. Таким образом, нам не нужно расширять контракт нашего web сервиса для передачи сообщений об ошибках, и в случае метода RemovePayment() мы можем вполне обойтись без возвращаемого значения. В случае неудачи удаления счета, информация о причине будет передана в сообщении об ошибке.
После всех изменений наш web сервис будет выглядеть так:

Выглядит значительно лучше, но проблемы остались.
Давайте посмотрим на метод CreatePayment(). Для того чтобы создать счет, нам надо передать пять параметров. С параметрами amount, date, desc, у нас проблем нет. Но вот откуда взять ссылки на получателя (recipient) и категорию (category)? Как я уже упоминал, эти данные представляют собой ссылки на элементы соответствующих справочников нашей системы. И теперь нам становится понятно, что для успешного использования нашего web сервиса, мы должны предоставить доступ к значениям этих справочников.


Таким образом, окончательный вид контракта нашего web сервиса дополнился двумя методами EnumRecipient() и EnumCategory() и двумя типами данных RecipientInfo и CategoryInfo. Их не было в первоначальном контракте и необходимость этих методов не определяется первоначальными требованиями. Они служат для обеспечения синтаксической полноты контракта нашего сервиса. Теперь потребитель данных сервиса может вызвать методы EnumRecipient() и EnumCategory() для получения списков получателей и категорий, выбрать из них необходимые значения, и затем вызвать метод CreatePayment() для создания счета.
Теперь мы можем сказать, что мы спроектировали функционально и синтаксически полный сервис. Также, наш сервис достаточно универсален, и с большой вероятностью его удастся использовать для интеграции с другими системами, перед которыми будут стоять похожие задачи. Кроме того, контракт сервиса и его WSDL описание, включают в себя полные схемы данных всех сообщений. Это очень важно для того, чтобы наш сервис смогли использовать инструменты интеграции типа BizTalk Server, Fiorano ESB, Sonic ESB и др.
На последнем моменте хочется заострить внимание. Формат данных, которыми обменивается сервис, очень важен. Разработчики нередко впадают в одну из двух крайностей. Первая из них, это использование в качестве формата для всех сообщений «голого Xml». Причины тому могут быть самые разные, от попыток использования существующего кода импорта - экспорта Xml данных, до слишком буквального понимания сути web сервисов, как механизма обмена Xml сообщениями. Недостаток такого подхода достаточно очевиден, - схема данных не попадает в WSDL описание контракта сервиса, и это затрудняет его использование. На мой взгляд, существует единственный случай, когда такой подход оправдан. Это случай, когда нам заранее не известен формат передаваемых данных. Во всех остальных случаях, следует использовать типизированные сообщения.
Вторая крайность, это противоположность первой, и выражается она в том, что разработчики пытаются использовать в контракте сервиса существующие в системе внутренние форматы представления данных. Действительно, если в системе уже определены структуры и классы для представления данных (Data Transfer Objects), то почему бы не использовать их в контракте сервиса? Это не всегда это хорошая идея. Внутренние форматы данных могут оказаться не удобными для клиента сервиса. Они могут иметь специфический формат, который не поддерживается клиентской стороной. Пример такого формата DataSet из Microsoft ADO.NET. Данные DataSet прекрасно преобразуются XML и могут быть использованы ASP.NET web сервисами. Однако, это внутренний формат Microsoft, который не является отраслевым стандартом, он имеет свои особенности форматирования Xml представления, которые могут затруднить использование этих данных другими программными платформами web сервисов. Существует масса случаев, в которых использование DataSet оправданно и удобно, но интеграционные сервисы не относятся к их числу.
Таким образом, общие рекомендации по проектированию форматов сообщений web сервисов сводятся к следующему. Всегда старайтесь использовать типизированные сообщения, формат которых описывается определенной Xsd схемой. Проектируйте формат сообщений исходя из функциональных требований, и лишь в том случае, когда полученный формат совпадает с внутренним форматом данных системы, можно подумать об использовании внутреннего формата.

Протокол взаимодействия и его влияние на контракт


Под протоколом взаимодействия web сервиса мы понимаем ту часть требований, которая описывает последовательность взаимодействия сервиса и клиента, направление передачи данных, а также такие аспекты поведения сервиса, как транзакционность, асинхронность, и т.д.
Протокол взаимодействия и контракт сервиса очень тесно связанны. Помимо достаточно простых случаев, когда существует один сервис и его клиент, существуют и более сложные, в которых протокол взаимодействия требует наличия двух и более сервисов. Примером такого протокола может служить протокол асинхронного взаимодействия ASAP
Я не открою большого секрета, если скажу, что отличным способом построить контракт сервиса (по крайней мере, в плане используемых операций) является использование UML диаграмм взаимодействия. Мое личное мнение, наилучшие результаты дает применение Sequence diagram. На рисунке приведена Sequence diagram взаимодействия клиента и сервиса из примера AccountsPayable, рассмотренного выше. К сожалению данный пример достаточно прост, чтобы почувствовать насколько Sequence diagram облегчают проектирование контракта сервиса.

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

Вопросы безопасности


После того, как контракт сервиса разработан, а иногда и раньше, перед проектировщиком в полный рост встают проблемы обеспечения безопасности. Времена, когда web сервисы называли незрелой технологией, не способной обеспечить безопасность данных, давно прошли. Web сервисы могут быть надежными и безопасными. А могут и не быть. Тут все зависит от нас.
Очертим круг вопросов, которые надо решить, для того чтобы спроектировать безопасный сервис:

  • Аутентификация клиентов сервиса

  • Авторизация клиентов сервиса

  • Безопасность передачи данных

  • Хранение удостоверений для подключения клиентов к сервису


Аутентификация – это процесс подтверждения подлинности пользователя на основе предъявленных им удостоверений. Надежность механизмов аутентификации является критичной для обеспечения безопасности приложения в целом. Поэтому сразу стоит забыть об «анонимном доступе». Наилучший сценарий обеспечения аутентификации, воспользоваться средствами, предоставляемыми платформой web сервисов, которую вы используете. Обычно для аутентификации используются специализированные протоколы (Kerberos, NTLM) и их поддержка встраивается в платформу. Реализация собственных механизмов аутентификации наверняка потребует значительных затрат и чревата потенциальными сложностями реализации и дальнейшей поддержки.
Авторизация - это процесс предоставления пользователю полномочий по доступу к функциям и данным. Естественно, для того чтобы авторизовать пользователя, предварительно он должен быть аутентифицирован. Уловите разницу между аутентификацией и авторизацией. Аутентификация отвечает на вопрос «кто» такой клиент, а авторизация – на вопрос «что» может делать этот клиент. В подавляющем большинстве случаев, бизнес правила по которым тому или иному пользователю предоставляются права доступа к тем или иным данным и операциям определяются в самом приложении. И, следовательно, авторизация – это область ответственности приложения, предоставляющего сервис. Существует множество методов, практик и шаблонов реализации механизмов авторизации, описание которых может быть предметом отдельной статьи.
Помимо аутентификации и авторизации, защита данных при транспортировке их между сервисом и его клиентом является третьей составной частью в обеспечении безопасности web сервиса. Степень защиты определяется характером данных. Различают два способа защиты данных: цифровая подпись и шифрование.
Цифровая подпись используется для подтверждения подлинности данных. Она не защищает данные от несанкционированного прочтения, потому что данные не шифруются. Цифровая подпись позволяет удостовериться в том, что данные принадлежат именно владельцу подписи, а также в том, что данные не были изменены с момента подписи. Механизм цифровой подписи довольно прост. Он основан на использовании не симметричных алгоритмов шифрования, в которых используется пара ключей, один из которых приватный (закрытый) а второй публичный (открытый). Особенность не симметричных алгоритмов состоит в том, что данные, которые зашифрованы одним ключом, можно расшифровать только другим ключом. Цифровая подпись формируется следующим образом. Для данных вычисляется контрольная сумма (хэш код), которая шифруется приватным ключом владельца цифровой подписи. Это и есть цифровая подпись, она добавляется к данным. Так же, к данным может быть добавлен открытый ключ. С помощью открытого ключа, любой пользователь может расшифровать цифровую подпись и получить контрольную сумму, которую можно сравнить с контрольной суммой рассчитанной над текущими данными и, таким образом узнать, изменились ли данные.
В случае, когда нам необходимо не только обеспечить неизменность данных, но и скрыть от посторонних их содержимое, применяется шифрование. Обычно, при передаче данных применяется схема с сеансовым ключом, на механизме которой я не буду останавливаться, поскольку обычно она обеспечивается на инфраструктурном уровне. Итак, цифровая подпись и шифрование являются основными механизмами защиты данных при передаче. Мы можем задействовать эти механизмы на уровне транспортного протокола, либо на уровне сообщений SOAP. Каждый из способов имеет свои преимущества и недостатки.
Для обеспечения защиты данных на уровне транспортного протокола обычно применяют хорошо зарекомендовавший себя механизм SSL. При этом между клиентом и сервером устанавливается защищенное соединение, в котором шифруется весь трафик. Преимущество данного подхода состоит в том, что он практически не требует дополнительных усилий со стороны разработчика (за исключением, может быть некоторых особенностей при установлении соединения). Основная работа по настройке защищенного SSL соединения производится при развертывании приложения. К недостаткам такого подхода можно отнести то, что шифруется весь трафик, а не только те данные, которые действительно являются конфиденциальными, и это требует больших затрат вычислительных ресурсов. Описание того, как использовать SSL совместно с web сервисами ASP.NET 1.1 вы можете найти в моей статье по адресу http://stump-workshop.blogspot.com/2006/10/web-https-ssl.html
Механизмы защиты данных на уровне SOAP сообщений строятся на использовании таких расширений SOAP протокола, как WS-SecureConversation, WS-Trust, WS-SecurityPolicy и WS-Security. Обычно поддержка этих спецификаций встроена на уровне платформы, реализующей web сервисы, и для разработчика они доступны как на декларативном уровне (атрибуты или конфигурирование) так и в виде API. К преимуществам использования данных механизмов относится их гибкость и универсальность. Вы можете использовать как шифрование, так и цифровую подпись. Можно обеспечить защиту только сообщений отдельных операций сервиса, и даже отдельных частей SOAP сообщения. К сожалению не все платформы web сервисов в полной мере поддерживают данные спецификации. Например, в широко распространенном .NET Framework 1.1 нет поддержки WS-Security. Поэтому при использовании данной платформы придется реализовывать защиту на транспортном уровне.
Наконец есть третий путь, - реализовать свой механизм защиты как, например, описано здесь. Следует, однако, понимать, что такой путь резко сокращает возможности использования вашего сервиса.
В заключении, стоит остановиться на таком вопросе, как хранение удостоверений для подключения к web сервисам. Мы уже говорили о том, что доступ к web сервисам следует предоставлять только аутентифицированным пользователям. Обратная сторона медали состоит в том, что нам необходимо указывать удостоверения (credentials) при подключении клиента к сервису. А следовательно, нам необходимо где-то хранить эти удостоверения. Когда нашей системе приходится взаимодействовать с несколькими сервисами, каждый из которых требует свои удостоверения, проблема приобретает особую остроту.
Что такое удостоверения. В большинстве случаев - это пара значений логин – пароль. Иногда это может быть клиентский сертификат или другой тип удостоверений, - все зависит от используемого протокола аутентификации. Следует четко понимать, что клиентские удостоверения относятся к данным, которые могут быть использованы для атаки злоумышленника на систему. Следовательно, эти данные требуют защиты. Вам следует учитывать это обстоятельство еще на стадии проектирования. При реализации интеграционных web сервисов, вам наверняка придется затратить некоторые усилия на разработку механизмов защищенного хранения клиентских удостоверений и их настройки / редактирования.

Вопросы реализации


Вопросы реализации web сервисов сильно зависят от платформы, с которой вы работаете, а их на сегодняшний день существует великое множество. Только Microsoft предлагает 4 платформы (ASP.NET 1.1, ASP.NET 2.0, WSE 1.0-3.0, WCF-Indigo). В мире Java их еще больше. Поэтому давать конкретные рекомендации весьма затруднительно. Однако есть моменты, на которые следует обратить внимание в любом случае.
Большинство платформ берут на себя формирование WSDL описания сервиса, предоставляя разработчику возможность работать с сервисом как с обычным классом. Поэтому, следует уделять постоянное внимание тем деталям, которые оказывают влияние на формирование правильного WSDL описания и XSD схем данных. К этим вещам относится использование Xml Namespace и префиксов, управление порядком сериализации данных, порядком и стилем генерации WSDL.
Следует стараться отделить бизнес логику от реализации сервиса. Хорошо, если у вас получится использовать единую бизнес логику внутри приложения и в web сервисе. В идеальном случае методы вашего web сервиса будут лишены всякой логики, кроме проверки параметров, формирования результатов и обработки ошибок, как показано на рисунке:

Заключение


Итак, в данной статье мы рассмотрели круг вопросов, связанных с проектированием интеграционных web сервисов.
Мы остановились на общих принципах концепции SOA. Рассмотрели практические вопросы проектирования контракта сервиса, обеспечения его функциональной и синтаксической полноты. Мы уделили внимание влиянию протокола взаимодействия на контракт сервиса. Рассмотрели варианты решения вопросов безопасности web сервисов. И в конце остановились на некоторых практических аспектах проектирования. Я надеюсь, что данная статья будет полезна вам при проектировании интеграционных web сервисов.

1 комментарий:

Анонимный комментирует...

Спасибо, достаточно лаконично и по делу.