«Совершенный Ajax» – новый подход к построению настоящих клиент-серверных web-приложений

«Совершенный Ajax» – новый подход к построению настоящих клиент-серверных web-приложений

«Совершенный Ajax» — новый подход к построению web-приложений, при котором web-сервер не генерирует ни строчки HTML-кода и взаимодействует с внешним миром только посредством web-служб; а клиентский интерфейс реализуется только на основе клиентских HTML, CSS, JavaScript.

Статья состоит из двух частей. В первой части — более живой и провокационной я постараюсь заинтересовать проблемой, рассказать о технологии «Совершенный Ajax» и показать ее применение на примере нашего проекта «Система Интерактивного Тестирования Знаний “Синтез”» (который имеет ряд интересных особенностей, таких, как использование серверного JavaScript на платформе Mozilla Rhino, прототипно-ориентированная ORM и поддержка SPARQL — языка запросов к Semantic Web).

Вторая часть – более занудная будет содержать много технических деталей и выйдет в следующий раз.

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

Попробуйте угадать: к какой архитектуре относятся web-приложения?

К клиент-серверной говорите? Я ожидал, что Вы так ответите :-)

    Сервер — отвечает за хранение данных и реализацию бизнес-логики приложения.

  1. Бизнес-логика не смешивается с пользовательским интерфейсом.
  2. Можно реализовать несколько клиентов с разными пользовательскими интерфейсами: интерфейс командной строки, оконный Windows-интерфейс, Flash, web-интерфейс, мобильный интерфейс и т.д.
  3. Клиентский компьютер не требователен к ресурсам;
  4. И т.д.

Но, относятся ли web-приложения к клиент-серверной архитектуре?

Действительно, в web-приложениях есть сервер, отвечающий за бизнес логику приложения.

Но! За реализацию интерфейса отвечает не клиент, а тоже сервер. На сервере происходит обработка клиентской формы. Сервер генерирует HTML-код пользовательского интерфейса.

Клиент, т.е. браузер лишь визуализирует уже готовый HTML-код интерфейса. Это, фактически, то же самое, что прицепить к серверу монитор и объявить этот монитор клиентом…

Здесь, правда, есть одна тонкость. Следует различать два понятия: web-приложения и систему «браузер — web-сервер». Web-приложения работают поверх браузера и web-сервера, так же как Java-приложения работают внутри JVM, приложения на .Net работают внутри .Net Framework, а протокол HTTP работает поверх TCP/IP.

Система «браузер — web-сервер» действительно имеет клиент-серверную архитектуру: web-сервер принимает и обрабатывает запросы, а браузер визуализирует результат.

Однако, здесь мы говорим не о системе «браузер — web-сервер», а о работающих внутри нее web-приложениях.

  1. Смешивание бизнес-логики и пользовательского интерфейса;
  2. Сложно реализовать несколько пользовательских интерфейсов;
  3. Сторонни программы не могут обращаться к серверу (если не написан специальный api);
  4. Большая часть нагрузки по обработке интерфейса ложится на сервер.
  5. И т.д.

Впрочем, мы знаем в истории пример подобной архитектуры. В 70-годы были распространены мейнфреймы. Мейнфрейм — такой огромный железный сундук (сервер), к которому подключались рабочие станции (клиенты). Причем, рабочая станция представляла собой просто монитор с клавиатурой. И любые действия клиента на рабочей станции обрабатывалось на сервере, порой даже такие как обработка нажатия на клавишу и обрисовка экрана [2] . Ну, мы знаем, насколько популярны мейнфреймы сегодня…

Конечно, в современных web-приложениях часть интерфейсной логики реализуется на клиенте с помощью JavaScript. Часть данных загружается с помощью Ajax и визуализируется именно на клиенте.

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

    Web-сервер:
      Реализует только бизнес-логику приложения и не генерирует ни строчки HTML-кода;

    Элементы управления (вкладки, меню, деревья) описываются высокоуровневыми HTML-конструкциями.

    «Совершенный Ajax» в нашем проекте

    Опишу эту архитектуру на примере нашего проекта «Система Интерактивного Тестирования Знаний “Синтез”».

    Сервер

    В концепции «Севершенный Ajax» сервер должен удовлетворять одному-единственному условию: не генерировать ни строчки HTML-кода и осуществлять связь с внешним миром посредством web-служб. Во всем остальном его реализация ничем не ограничена.

    Здесь я опишу структуру сервера в нашем проекте, т.к. она имеет ряд интересных особенностей: использование серверного JavaScript на платформе Mozilla Rhino, прототипно-ориентированная ORM и возможность использования SPARQL — языка запросов к Semantic Web.

    Однако, Ваша реализация сервера может быть совершенно иной и совсем не похожей на нашу.

    Архитектура сервера

    • СУБД — хранит данные.

    • Все данные хранятся в обычной реляционной базе данных.

    Объектное ядро бизнес-логики

    • Вся объектная модель приложения и его бизнес-логика заключена в прототипно-ориентированном ядре.

    Благодаря этому, наш серверный JavaScript не становится «вещью в себе», а может использовать все обилие наработок мира Java.

    Прототипно-ориентированная ORM

    • ORM служит для связи реляционной БД с прототипным объектно-ориентированным ядром бизнес-логики.

    Реляционная модель БД гораздо ближе к прототипной модели ООП, нежели к классовй. Поэтому, применение прототипного похода решает ряд проблем, присущих современным класс-ориентированным ORM (см., например, статью Теда Ньюарда «Вьетнам компьютерной науки»).

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

    В частности, это дает возможность обращаться к БД на SPARQL — языке запросов Semantic Web.

    Web-сервер

    • Web-сервер выполняет только одну-единственную задачу — связывает ядро бизнес-логики с внешним миром посредством web-служб.

    Клиент

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

    Однако, оно всегда имеет в комплекте «родной» web-интерфейс.

    Здесь я опишу его структуру.

    Архитектура клиента

    • Интерфейсное ядро — объектно-ориентированная библиотека, реализующая всю клиентскую логику и управляющая интерфейсом клиента.

    Интерфейсное ядро

      Реализует интерфейсную логику приложения.

    Это дает неограниченные возможности для создания мэшапов. В отличие от обычных мэшап-приложений, таких как GMaps, YouTube и т.д., которые позволяют встраивать только небольшую часть интефейса; в нашем приложении интерфейс может встраиваться полностью.

    Например, благодаря этому, на стороннем сайте можно не только разместить модуль прохождения тестирования, но и модуль редактирования тестов, а также управления правами пользователей.

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

    Библиотека обертка

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

    Поэтому, гораздо удобнее работать через объектно-ориентированную библиотеку-обертку над web-службами. Библиотека обертка позволяет прозрачно работать с серверной объектной моделью приложения.

    Нам надо получить объект Морковкин Вася и сделать его учеником 3 «А» класса.

    Вместо низкоуровневой работы с web-службами, мы прозрачно работаем с объектной моделью приложения посредством библиотеки-обертки Sintez .

    //Получаем с сервера объект Морковкин Вася <br> var objStudent1 = Sintez.getStudent ( "this.firstName = 'Вася' and this.secondName = 'Морковкин'" );<br> //Получаем объект 3 "А" класс <br> var objClass1 = Sintez.getClass ( "this.getClassNuber() = 3 and this.liter = 'А'" );<br> //Делаем Васю учеником этого класса <br> objClass1.addStudent (objStudent1);<br>

    А уже библиотека-обертка кодирует вызов методов объектов как команды web-служб, пакует объекты перед отправкой их на сервер и распаковывает после получения.

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

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

    Семантическая верстка

    • Весь пользовательский интерфейс реализуется на основе чистых xHTML, CSS и JS.

    Несмотря на сильную недооцененность разработчиками, xHTML/CSS/JS является очень мощной и гибкой технологией построения интерфейсов.

    И если при старом подходе, когда HTML-код генерировался сервером, мы, несмотря на все уродство, могли себе позволить низкоуровневый несемантический подход;

    то при подходе «Совершенный Ajax» мы просто обязаны использовать высокоуровневую семантическую верстку!

    Например, меню или дерево описывается как обычный список, а вкладки, как набор div ’ов.

    Библиотека контролов

    • Библиотека контролов придает HTML-конструкциям внешний вид и функциональность соответствующего элемента управления.

    Работа с контролом происходит через вызов методов объекта.

    Поскольку контролы не меняют код своей HTML-конструкции, элемент управления может быть «на лету» превращен в другой элемент простой заменой JS и CSS-классов.

    Дерево описывается не мешаниной тегов, а единой высокоуровневой HTML-кострукцией: вложенным списком.

    < ul id = "ulTree1" > <br> < li > <br> Элемент 1<br> < ul > <br> < li > <br> Элемент 1-1<br> </ li > <br> < li > <br> Элемент 1-2<br> </ li > <br> </ ul > <br> </ li > <br> < li > <br> <!--. --> <br> </ li > <br> </ ul > <br>