Алик Кириллович

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

17 декабря 2008 г.

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

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

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

 

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

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

Что ж, давайте разберёмся. В клиент-серверной архитектуре выделяют [1]:

Реализация бизнес-логики на сервере и взаимодействие с пользователем на клиенте чётко разделены.

Преимущества клиент-серверной архитектуры очевидны; мы их все знаем:

  1. Бизнес-логика не смешивается с пользовательским интерфейсом.

  2. Можно реализовать несколько клиентов с разными пользовательскими интерфейсами: интерфейс командной строки, оконный Windows-интерфейс, Flash, web-интерфейс, мобильный интерфейс и т.д.

  3. Клиентский компьютер не требователен к ресурсам;

  4. И т.д.

 

Но, относятся ли web-приложения к клиент-серверной архитектуре? 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 и визуализируется именно на клиенте.

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

Так вот, я предлагаю подход «Совершенный Ajax», который призывает развить идею Ajax до логического конца и полностью отказаться от использования сервера для реализации пользовательского интерфейса web-приложений.

Подход «Совершенный Ajax» построен на следующих принципах:

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

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

Сервер

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

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

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

Архитектура сервера
СУБД
СУБД
Объектное ядро бизнес-логики
Ядро бизнес-логики
Прототипно-ориентированная ORM
ORM
Web-сервер
Web-сервер

Клиент

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

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

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

Архитектура клиента
Интерфейсное ядро
Интерфейсное ядро

Интерфейсное ядро — объектно-ориентированная JavaScript-библиотека, управляющая всем клиентским web-интерфейсом:

Библиотека обёртка
Объектно-ориентированная библиотека-обёртка над web-службами
Семантическая вёрстка
Семантическая вёрстка
Библиотека контролов
Библиотека контролов

 

Подробности технической реализации подхода «Совершенный Ajax» — во второй части.

Примечания

  1. Речь идёт о клиент-серверных приложениях с конечным пользователем. В клиент-серверных приложениях вроде «клиент — сервер базы данных», пользовательский интерфейс, разумеется, отсутствует.

  2. Позже, у мейнфреймов появились так называемые «умные клиенты», которые обладали собственным процессором и памятью, а наиболее продвинутые могли даже проверить форму перед отправкой на сервер. Это очень напоминает нынешнюю робкую попытку передать часть интерфейсной логики web-приложения на клиент с помощью Ajax.

Библиотека подсветки синтаксиса в этой статье основана на «highlight.js» от Ивана Сагалаева.

См. также

15 комментариев:

  1. Владимир
    02.01.2009, 15:35

    Попробую резюмировать :)

    Делаем передачу данных в формате XML или JSON (или каком-нибудь еще) и получаем "Совершенный AJAX".

    Не понятно о какой библиотеке контролов идет речь. Вашей собственной (вы ее продаете или свободно распространяете?) или существующей?

  2. Алик Кириллович
    06.01.2009, 03:18

    @Владимир

     

    Делаем передачу данных в формате XML или JSON (или каком-нибудь еще) и получаем "Совершенный AJAX".

    Главное в подходе «Совершенный AJAX» то, что:

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

    А XML или JSON — это лишь средство для работы web-служб.

     

    Не понятно о какой библиотеке контролов идет речь. Вашей собственной (вы ее продаете или свободно распространяете?) или существующей?

    При подходе «Совершенный AJAX» можно использовать любую клиентскую библиотеку контролов — как самописную, так и уже готовую: ExtJS, Dojo, jQuery UI и т.д.

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

    В нашем проекте мы, по некоторым причинам, используем собственную внутреннюю библиотеку; однако, в принципе, при подходе «Совершенный AJAX» можно использовать библиотеки любых производителей.

  3. Владимир
    07.01.2009, 13:41

    >> web-сервер не генерирует ни строчки HTML-кода

    Допустим, серверный передает дату. Он может сделать несколькими способами:

    1) как метку времени;

    2) отформатированную функцией date (или аналогичной).

    Формально ни в том, ни в другом случае HTML разметки нет.

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

    Поэтому, на мой взгляд, требование "web-сервер не генерирует ни строчки HTML-кода" нужно изменить на "web-сервер не форматирует данные вообще".

  4. Глеб Белогорцев
    27.01.2009, 11:05

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

    - большАя часть нагрузки перекладывается на клиентскую машину. Уже сейчас есть сайты, использующие AJAX, при просмотре которых мой комп начинает тормозить. А уж если в JS будет какая-нибудь ошибка, приводящая к утечкам памяти...

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

    - если при обычном "несовершенном" AJAX поисковики проиндексируют на сайте хоть что-то, то тут, подозреваю, с индексацией будет совсем плохо.

    Так что этот принцип подходит далеко не для всех проектов.

    Кстати, а что вы используете для обмена данных между JS и сервером: JSON или XML (просто статистику собираю)?

  5. Алик Кириллович
    27.01.2009, 16:50

    @Глеб Белогорцев

    Так что этот принцип подходит далеко не для всех проектов.

    Совершенно правильно. Для сайтов, разумеется, следует использовать традиционный подход.

    Архитектура «Совершенный Ajax» предназначена для web-приложений (программ).

    Это и решает многие приведенные Вами проблемы:

     

    с индексацией будет совсем плохо

    web-приложениям (таким, как GMail, GMaps и т.д.) не требуется индексация в поисковиках.

     

    стандартный интерфейс становится недоступным для альтернативных клиентов, типа мобильных или текстовых браузеров

    Вообще, обычные web-приложения итак далеко не всегда доступны для альтернативных клиентов.

    При подходе «Совершенный Ajax», сделать интерфейс доступным для альтернативных клиентов, становится даже проще, чем в обычных приложениях.

    Поскольку элементы управления (вкладки, меню, деревья) получаются из соответствующих HTML-конструкций простым навешиванием CSS и JS-классов, их очень просто адаптировать для альтернативных устройств.

    Например, если у нас есть контекстное меню (требующее правую кнопку мыши и не работающее на мобильных устройствах), его можно превратить в понятный для мобильника многоуровневый список, просто заменив соответствующие CSS и JS-классы.

    От клиента требуется только поддержка JavaScript.

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

  6. miraz
    15.02.2009, 03:46

    Ждем продолжения!надеюсь будет!

  7. MX
    22.02.2009, 05:59

    Маленький технический вопрос:

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

    Посмею предположить, что в данном коде выполняется как минимум три синхронных AJAX-запроса. я прав?

  8. Алик Кириллович
    22.02.2009, 11:32

    @MX

    Посмею предположить, что в данном коде выполняется как минимум три синхронных AJAX-запроса. я прав?

    Да, действительно, в приведенном примере генерируются три запроса (по одному на каждую операцию).

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

  9. ZeusTheTrueGod
    15.05.2009, 14:42

    //Получаем с сервера объект Морковкин Вася

    var objStudent1 = Sintez.getStudent ("this.firstName = `Вася` and this.secondName = `Морковкин`");

    //Получаем объект 3 "А" класс

    var objClass1 = Sintez.getClass ("this.getClassNuber() = 3 and this.liter = `А`");

    //Делаем Васю учеником этого класса

    objClass1.addStudent (objStudent1);

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

    Получается, что надо на сервер передавать описание действий, а сервер их должен выполнить и отдать ответ.

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

  10. dizelbox
    13.06.2009, 00:27

    Это хорошая идея по поводу совершенного AJAX, но все равно предварительно потребуется каким-то образом иметь у пользователя все необходимые скрипты и непосредственно странички.

  11. kep
    23.08.2009, 08:12

    Тема интересная, без сомнения...

    И у нее есть будущее, так как, именно в этом направлении рынок и собирается развиваться!

    Помнится для одной практической работы - " ... "

    На клиент изначально засылалась оболочка, а в виде "транспортного протокола общения" был выбран XML...

    А плюсы всего этого:

    + Логика отделена от данных

    + Возможность смены дизайна

    + И самый главный не нужно каждый раз генерировать на сервере "визуальную" составляющую...

    + ...

    + ...

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

  12. Сергей Титенко
    11.09.2009, 18:55
    //Получаем с сервера объект Морковкин Вася
    var objStudent1 = Sintez.getStudent ("this.firstName = `Вася` and this.secondName = `Морковкин`");
    
    //Получаем объект 3 "А" класс
    var objClass1 = Sintez.getClass ("this.getClassNuber () = 3 and this.liter = `А`");
    
    //Делаем Васю учеником этого класса
    objClass1.addStudent (objStudent1);
    
    

    Алик, я солидарен с ZeusTheTrueGod

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

    Т.е. строчку objClass1.addStudent (objStudent1) имеем право выполнять только после того, как убедимся, что на первые два вызова сервер уже ответил.

  13. Константин
    14.12.2009, 05:11

    @ZeusTheTrueGod, @Сергей Титенко

    откуда Вы взяли, что XHR выполняется асинхронно ???

    var data = getData(); // XMLHttpRequest

    alert ("data is " + data);

    такая конструкция работает, хотя если бы она была асинхронной - то алерт всегда давал бы <null>, "" или "undefined".

  14. Barbie
    11.06.2010, 23:38

    Тема интересная.

    Но Ajax несомненно нуждается в доработке. Многие нюансы ведут к его некорректной работе.

  15. Vadym77
    25.08.2010, 12:04

    я вот уже полгода активно учу аякс, но с каждым днем узнаю что-то новое

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

Имя:
E-mail (не публикется):
Веб-сайт (ссылки не «глушатся» nofollow):
Текст:
Вы можете использовать BBCode:
[b]жирность[/b]
[i]курсив[/i]
[u]подчеркивание[/u]
[s]перечеркивание[/s]
[url]http://www.example.com[/url]
[url=http://www.example.com]Текст ссылки[/url]
[quote]Цитата[/quote]
[code]
код на
  языке
программирования
[/code]
[list]
* Список
* Список
* Список
[/list]

Статьи

About

Подписка

Ждите...

Valid XHTML 1.0 Strict © Алик Кириллович, 2008—2010