Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 11855
Последний выпуск: 19.06.2015

Как не нужно писать веб сервисы

Автор: Никита Зимин
Дата: 5 ноября 2002 года

Суммарий нашего опыта использования технологии .Net XML Web Services, представленный в виде "от противного".

Как НЕ надо писать веб-сервиса

Из всего богатого арсенала платформы .Net пока наиболее востребованными оказались технологии ASP.Net и Web Services, используемые для написания серверных приложений. До массового написания на .Net клиентских приложений дело еще не дошло, хотя сообщения об этом уже пояляются.

С ASP.Net все понятно - ее можно рассматривать просто как удобную замену ASP. Что касается web-services - что же это на самом деле?

Сразу оговорюсь, что в рамках этой статьи мы рассматриваем только "XML Web Services Created Using ASP.NET".

Функционально, Web Service - это класс, со своим набором свойств и методов, которые доступны для вызова через удаленное соединение по протоколу HTTP. При каждом вызове как запрос, так и ответ представляется в виде XML. Более подробное описание вы найдете в статье [1].

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

Этот текст обобщает опыт использования веб-сервисов в наших проектах. Я не претендую на полноту или истину в последней инстанции. Не забывайте что нет правил без исключений. Мне лишь хотелось бы чтобы вы не повторили описанных здесь ошибок.

Веб-сервис как класс

В самом деле - веб-сервис представляется классом. Он порождается от класса System.Web.Services.WebService, имеет свои свойства и методы. А раз это класс, то можно создавать экземпляры объектов этого класса. Тогда можно делать и так:

    Dim ws As FooWS.Foo = New FooWS.Foo
    ws.Login(name, password)
    ws.GetData()
    ws.SaveData()
    ws.Logout()

Вроде бы все прекрасно - за одним исключением. Переменная ws хранит ссылку на объект, но это - не экземпляр веб-сервиса - ведь тот объект может быть создан только на сервере. Вызовом New FooWS.Foo мы создаем proxy-класс, обращения к которому приводят к вызовам веб-методов.

В общем случае, при КАЖДОМ вызове экземпляр (объект) класса FooWS.Foo создается на сервере заново. А значит, значения, хранящиеся в этом объекте, теряются. Тем самым, состояние этого объекта не хранится между вызовами (что и называется "stateless").

Поскольку класс является stateless, то и писать его нужно соответственно:

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

Наследование на веб-сервисах

Как и для любых других полноценных классов, для веб-сервисов можно применять наследование. Вы даже можете составить целую иерархию таких классов. О преимуществах говорить не буду - скажу только о недостатках.

Сколько бы ни было у вас веб-сервисов - 1 или 100, располагаются ли они в одном проекте или в нескольких - но чтобы использовать их где-то еще кроме вашего проекта вы должны на КАЖДЫЙ из них установить ссылку (web-reference). Это несколько ограничит ваши возможности как великого объектного архитектора.

Каждая web-reference задает свой namespace (например, в приведенном выше примере ссылка будет называться FooWS и namespace будет иметь то же название). Если вы породите два класса (например, Foo1 и Foo2) от одного родительского класса (Foo, порожденного от WebService), то для их использования на клиенте вам придется завести две ссылки (FooWS1 и FooWS2), причем объекты, объявленные в проекте веб-сервиса глобально, будут доступны на клиенте под двумя именами (в нашем примере FooWS1.MyDataSet и FooWS2.MyDataSet). Это только усложняет программирование и ничего полезного в себе не несет.

Итак.

Наследование на веб-сервисах не дает нам фактически ничего, кроме новых проблем. Инкапсуляция данных в класс веб-сервиса бессмысленна - поскольку эти данные не сохраняются между вызовами. Получается, что от объектного подхода, применительно к веб-сервисам, практически ничего не остается.

Скорее это библиотека статических методов, собранных в одном модуле под одним именем, причем вызовы этих методов довольно "тяжелы" (не в смысле трудности в реализации или использовании, а в смысле эффективности).

Передача параметров: Упаковка параметров в строку или XML

VB6, предшествующий своему насквозь объектному собрату VB.Net, накладывал определенные (и довольно суровые) ограничения на передачу структур данных в виде параметров методов и в качестве возвращаемых значений. Эти правила тем более суровы если речь идет о межкомпонентных вызовах.

Поэтому для VB-программиста является привычным и естественным передавать сложные данные каким-либо другим способом - например, упаковав все параметры в строку. Более того, шумиха вокруг XML приводит к тому что многие считают естественным упаковывать и параметры, и результат, в формат XML.

VB.Net лишен недостатка своего "младшего" собрата - вы можете как передавать, так и возвращать сложные структуры данных. Для веб-сервиса автоматически создается proxy-класс, решающий проблемы преобразования любых передаваемых типов и структур в/из XML. И запрос, порождаемый вызовом, и результат передаются в виде XML.

Тем самым, ручная упаковка в/из строки или (тем более) XML только добавит лишний код - а возможно и лишние ошибки.

[Тут надо заметить, что сложные объектные структуры (передаваемые web-сервисам или возвращаемые от них) могут создаваться на основе дополнительной библиотеки классов, либо использовать возможности DataSet. В любом случае, библиотека классов или схема данных DataSet должна присутствовать и на сервере, и на клиенте.]

Использование веб-сервиса как компонента

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

В чем же недостатки этого пути?

1. Вызовы веб-методов очень тяжелы.

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

Такая технология позволяет выполнять вызов используя протокол HTTP, работать через firewall, но зачем вам все это, если компоненты вашей системы находятся на одном компьютере или в локальной сети? Подумайте, может быть лучше использовать COM+-компоненты? - их тоже можно написать на .Net.

2. Методы веб-сервиса не могут быть частью транзакции

Компоненты всегда связаны между собой, и вызов метода одного модуля часто приводит к нескольким вызовам в "нижележащих" компонентах.

Важно знать, что вызов веб-сервиса не может быть частью транзакции. Каждый веб-сервис функционирует в своей среде и состояние сессии, связанное с транзакцией, не передается.

Это означает, что сценарий обновления данных в базе с последующим принятием/откатом (commit/rollback) здесь неприменим: откат (rollback) изменений, сделанных в ходе вызова веб-метода, не произойдет.

Тем не менее, в рамках одного веб-метода транзакция может быть создана. См. [2].

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

Резюме - а как надо?

Вопрос о том, целесообразно ли использование той или иной технологии, всегда можно решить только применительно к конкретной задаче. Но можно заранее сказать, что web-service будет хорошим решением в каком-либо из следующих условий:

  • вам нужно предоставить открытый интерфейс к готовой системе;
  • клиенты могут располагаться за firewall;
  • клиенты написаны в другой среде (например Java) или в другой операционной системе;
  • клиенты системы являются сторонними по отношению к вам;
  • клиентом системы является другое крупное приложение;
  • требуется интеграция системы с существующими (старыми) приложениями.

Ссылки

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

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог