Архитектура веб приложений
Архитектура веб-приложений. Стек Spring MVC + AngularJs
Ниже вашему вниманию предлагается перевод, посвященный разработке веб-приложений. Описываемый автором стек демонстрирует интересную возможность комбинации Java и JavaScript, а также позволяет по-новому взглянуть на создание одностраничных веб-приложений.
При этом поинтересуемся, хотите ли вы увидеть на полке перевод следующих книг по Spring и AngularJS
Технологии Spring MVC и AngularJs вместе образуют по-настоящему продуктивный и привлекательный стек для разработки веб-приложений, в особенности таких, где требуется интенсивно работать с формами.
В этой статье будет рассмотрено, как построить именно такое приложение. Этот подход мы сравним с другими имеющимися вариантами. Полнофункциональное защищенное веб-приложение, написанное с применением Spring MVC/AngularJs находится в этом репозитории на GitHub.
Мы рассмотрим следующие вопросы:
- Архитектура одностраничного веб-приложения Spring MVC + Angular
- Как структурировать пользовательский веб-интерфейс при помощи Angular
- Какие библиотеки JavaScript/CSS хорошо сочетаются с Angular
- Как построить машинный интерфейс REST API с применением Spring MVC
- Защита REST API при помощи Spring Security
- Сравнение этого подхода с другими, где весь проект реализуется на Java?
Архитектура одностраничного веб-приложения Spring MVC + Angular
Приложения для корпоративной среды, предполагающие интенсивную работу с формами, лучше всего делать в виде одностраничных веб-приложений. Основная идея, выделяющая их на фоне более традиционных серверных архитектур — создание сервера в виде набора переиспользуемых REST-сервисов, не сохраняющих состояния. В контексте MVC важно изъять контроллер из машинного интерфейса и перенести его в браузер:
Клиент поддерживает шаблон MVC и содержит всю логику представления, разделяемую на уровень представления, уровень контроллера и уровень клиентских сервисов. Когда приложение будет запущено, клиент и сервер будут обмениваться только данными JSON.
Как реализуется машинный интерфейс?
Машинный интерфейс корпоративного приложения, обладающего клиентской частью, логично и удобно писать как REST API. Та же технология может использоваться для предоставления веб-сервисов сторонним приложениям. Зачастую в таких случаях исчезает необходимость в отдельном стеке веб-сервисов SOAP.
C точки зрения DDD модель предметной области остается на машинном интерфейсе, там же, где находятся уровень сервисов и уровень сохраняемости. По сети передаются лишь DTO, но не модель предметной области.
Как структурировать клиентскую часть веб-приложения при помощи Angular
Клиентская часть должна выстраиваться вокруг модели, относящейся к представлению (а не к предметной области). Здесь должна обрабатываться только логика представления, но не бизнес-логика. В клиентской части выделяется три уровня:
Уровень представления состоит из HTML-шаблонов, таблиц CSS и директив Angular, соответствующих различным компонентам пользовательского интерфейса. Вот пример простого представления для формы входа:
Уровень управления (контроллера)
Уровень управления состоит из контроллеров Angular, склеивающий вместе данные, извлекаемые, соответственно, из машинного интерфейса и из представления. Контроллер инициализирует модель представления и определяет, как представление должно реагировать на изменения модели и наоборот:
Одна из основных задач контроллера — выполнять валидацию в клиентской части. Все подобные клиентские валидации предусматриваются лишь для удобства пользователя — например, с их помощью удобно немедленно информировать пользователя о том, что поле обязательно для заполнения.
Все акты клиентской валидации должны повторяться на машинном интерфейсе (на уровне сервисов) из соображений безопасности, поскольку клиентскую валидацию легко обойти.
Уровень клиентских сервисов
В контроллеры Angular можно внедрить набор сервисов Angular, которые могут взаимодействовать с машинным интерфейсом:
Давайте рассмотрим, какие еще библиотеки нам понадобятся, чтобы запустить работу клиентской части.
Какие библиотеки JavaScript/CSS должны дополнять Angular?
Angular уже предоставляет значительную часть функционала, необходимого для создания клиентской части вашего приложения. Вот некоторые интересные дополнения для Angular:
- Библиотека PureCSS от Yahoo. Она написана на чистом CSS, обеспечивает удобное оформление при помощи имеющихся в ней тем и весит всего 4k. Ее компонент Skin Builder позволяет с легкостью сгенерировать тему, исходя из основного цвета. Это решение из разряда BYOJ (Bring Your Own Javascript), помогающее писать код «в духе Angular».
- Библиотека для операций с данными в стиле функционального программирования. Кажется, эта библиотека может похвастаться превосходной поддержкой и документацией, непревзойденной со времен lodash.
Вооружившись двумя этими библиотеками и Angular, можно построить практически любое приложение с формами, больше практически ничего не требуется. В зависимости от специфики вашего проекта могут пригодиться и некоторые другие библиотеки:
- Удобно иметь систему модулей наподобие requirejs, но поскольку система модулей Angular не обрабатывает извлечения файлов, возникает определенное дублирование при объявлении зависимостей requirejs и модулей angular.
- Angular-модуль CSRF, предотвращающий атаки, связанные с подделкой межсайтовых запросов.
- Модуль интернационализации
Как построить машинный интерфейс REST API при помощи Spring MVC
Этот машинный интерфейс содержит обычные уровни:
- Уровень маршрутизации: определяет, какие точки входа сервисов соответствуют конкретным HTTP URL, и как будут считываться параметры из HTTP-запроса
- Уровень сервисов: содержит лишь бизнес-логику (например, обеспечивает валидацию), определяет область применения бизнес-транзакций
- Уровень сохраняемости: Отображает базу данных на объекты предметной области, хранящиеся в памяти и наоборот
В настоящее время наилучшая конфигурация Spring MVC подразумевает только использование Java-конфигурации. Даже web.xml
уже, в общем, не требуется. См. здесь пример полностью сконфигурированного приложения, где задействуется только Java.
Уровни сервисов и сохраняемости создаются по обычной модели DDD, поэтому давайте обратим внимание на уровень маршрутизации.
Те же аннотации Spring MVC, что применяются для создания приложения JSP/Thymeleaf, также могут использоваться и при разработке REST API.
Большая разница заключается в том, что методы контроллера не возвращают объект String, который бы определял, какой шаблон представления следует отобразить. Вместо этого применяется аннотация@ResponseBody, указывающая, что возвращаемое значение метода контроллера должно непосредственно отображаться и стать телом отклика:
Если все методы класса должны аннотироваться @ResponseBody
, то лучше снабдить весь класс аннотацией @RestController
.
Если добавить библиотеку Jackson JSON, то возвращаемое значение метода будет преобразовываться непосредственно в JSON без какой-либо дальнейшей конфигурации. Кроме того, это значение можно преобразовать в XML или другие форматы, в зависимости от значения HTTP-заголовка Accept
, указанного клиентом.
Здесь показана пара контроллеров, у которых сконфигурирована обработка ошибок.
Как защитить REST API при помощи Spring Security
Интерфейс REST API можно защитить при помощи конфигурации Spring Security Java. В данном случае целесообразно использовать форму входа с аутентификацией HTTP Basic в качестве резервного варианта, а также подключать защиту от CSRF и возможность жестко задавать, что все методы машинного интерфейса могут быть доступны только через HTTPS.
Таким образом, машина предложит пользователю форму для входа, а после успешного входа присвоит сеансовый cookie браузерным клиентам, но при этом будет работать и с другими клиентами, поддерживая откат к обычному HTTP в случаях, когда учетные данные будут передаваться при помощи HTTP-заголовка Authorization.
В соответствии с рекомендациями OWASP REST-сервисы можно программировать с минимальным сохранением состояния (вся информация о состоянии сервера ограничивается тем сеансовым cookie, который использовался для аутентификации). Это делается, чтобы не пересылать учетные данные по сети при каждом запросе.
Вот пример конфигурирования безопасности REST API:
Такая конфигурация учитывает аутентификацию лишь в контексте безопасности, при этом стратегия авторизации выбирается в зависимости от требований безопасности, предъявляемых API. Если вам нужен тонкий контроль над авторизацией, познакомьтесь со списками контроля доступа Spring Security ACLs и проверьте, подходят ли они для решения стоящей перед вами задачи.
Теперь сравним такой способ создания веб-приложений с другими распространенными подходами.
Сравнение стека Spring MVC/Angular с другими распространенными вариантами
Такой способ использования JavaScript в клиентской части и Java — в работе с базой данных упрощает рабочий процесс и повышает его продуктивность.
Когда машинный интерфейс уже работает, не требуется никаких специальных инструментов или плагинов, чтобы разогнать горячее развертывание в клиентской части на полную мощность: просто опубликуйте ресурсы на сервере при помощи IDE (например, нажмите Ctrl+F10 в IntelliJ) и обновите страницу в браузере.
Классы машинного интерфейса по-прежнему можно перезагрузить при помощи JRebel, но в клиентской части ничего отдельно делать не требуется. В принципе, можно выстроить всю клиентскую часть, сымитировав машинный интерфейс при помощи, скажем, json-server. В таком случае различные специалисты смогут параллельно разрабатывать клиентскую часть и машинный интерфейс, если это потребуется.
Повышение продуктивности или полностековая разработка?
По моему опыту, возможность непосредственно редактировать HTML/CSS без всяких уровней косвенности (см. например общее сравнение Angular с GWT и JSF) помогает снизить умственную нагрузку и не усложнять работу. Цикл разработки «отредактировать-сохранить-обновить» очень быстр и надежен, позволяет работать значительно продуктивнее.
Наибольший выигрыш в продуктивности достигается в случаях, когда одни и те же разработчики пишут как клиентскую часть на JavaScript, так и машинный интерфейс на Java, поскольку для реализации большинства возможностей обычно требуются одновременные изменения и там, и там.
Потенциальный недостаток данного подхода таков: эти разработчики должны знать и HTML, и CSS, и JavaScript, но в последние годы такая компетенция встречается все чаще.
Мой опыт подсказывает, что полностековая разработка позволяет реализовывать в клиентской части самые непростые кейсы за толику того времени, которое требуется на создание полномасштабного решения на Java (дни, а не недели), и такой рост продуктивности определенно оправдывает дополнительное обучение.
Комбинация Spring MVC и Angular позволяет действительно по-новому взглянуть на разработку веб-приложений, связанных с интенсивным заполнением форм. Данный подход настолько повышает продуктивность, что к нему определенно следует присмотреться.
Отсутствие привязки к состоянию сервера между запросами (если не считать аутентификации с cookie) по определению избавляет нас от целого класса багов.
Дополнительно предлагаю ознакомиться на github с этим приложением.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Какую технологию выбрать или архитектура современных приложений
ru-RU | создано: 13.05.2015 | опубликовано: 13.05.2015 | обновлено: 02.01.2018 | просмотров за всё время: 10369
Так получилось, что у меня есть некоторый опыт по разработки приложений. Начала отсчета 2001 год, то есть когда C#.NET был у истоков. На сегодняшний день, в мой адрес звучат множество вопросов: Какие технологии актуальны? Какую архитектуру из каких технологий построить? Перспективы развития той или иной технологии? В общем, в этой статье поговорим про выбор технологии.
Направление
Ни для кого не секрет, что в мире IT существует множество технологий. Даже если говорить только о клиентской (front-end) части, то можно, навскидку, вспомнить такие как: AngularJS, KnockoutJS, EmberJS, BreezeJS, DurandalJS и другие. Если же говорить о серверной (back-end) части ПО, тут в последние время появилось тоже очень много возможностей, как то: Web API, OData, ASP.NET MVC, WCF-services. Хотя Microsoft и планирует объединить первые три в одно целое под названием MVC 6, технологии всё равно разные.
Так уж получилось, что я имею опыт работы c платформой .NET. А если конкретно, то ASP.NET на C# (хотя опыт есть и на Windows Mobile, Windows Phone, WPF, WCF и другие платформы). Когда-то я начинал с ASP.NET WebForms, позже перешел на ASP.NET MVC (о чем не жалею ни секунды). И в связи с этим, повествование будет идти касательно NET. А также мы поговорим о JavaScript.
История о JavaScript
В стародавние времена, когда .NET еще не было и в мыслях, была такая платформа ASP. Я обратил на нее внимание только начиная с версии 3.0. В те далекие времена, язык JavaScript (JS) был всего лишь дополнением к основному языку ASP 3.0 (серверная разметка в HTML). JS — выполнял вспомогательные функции для решения задач на клиентской стороне, потому что JavaScript выполняться в браузере на клиенте. Мелкие функции, простые расчеты и другие нетребовательные операции: отобразить сообщение об ошибке, проверить ввод пользователя, подставить значение по умолчанию и прочие функции – вот для чего в основном программисты использовали JS.
На данный момент, вот уже в течении 3-5 лет JS перерос в нечто большее, чем просто вспомогательный язык. Он приобрел статус самостоятельного основного языка для разработки по web. Язык может теперь работать напрямую с http-сервером (node.js), что ставит его на один уровень с другими языками.
Front-End
Выбор клиентской части от основной архитектуры приложения следует начать с определения, “что есть что”. Перед тем как начать выбирать, приведу схему архитектуры современного web-приложения.
Итак, давайте рассмотрим часть “Клиент”, ведь именно это и есть Front-End. Желтая зона, состоящая из четырех подзон представляет собой простые понятия:
- базовые операции – определение namespace’ов, утилиты, настройки приложения, хелперы, вспомогательные функции и классы и другие обобщенные сборки полезных вещей. Это своего рода “кладовочка”, в которой полно разного инструмента и расходного материала на выбор. Здесь лежат базовые определения для приложения.
- Widgets – контролы и компоненты сторонних разработчиков, например, jQuery UI, Bootstrap и другие полезные компоненты (контролы) и UI-фреймворки.
- MV* frameworks – фреймворки на JavaScript, которые отвечают некоторым требованиям, то есть “знают” о маршрутизации (router), привязка данных (data-binding), шаблонные представления (template/views), модели (models) и доступ к данным (data access). MV* – представляет собой семейство паттернов MVC, MVP, MVVM. Примерами таких фреймворков могут послужить: backbone.js, knockoutjs, maria.js.
- JavaScript-библиотеки – сборки сторонних разработчиков, именно те, что являются вспомогательными инструментами или базовыми основами. Например, jQuery, underscore.js, moment.js и другие.
Всё, что объединено в нижнем блоке раздела “Клиент” можно назвать “App framework”. Реализации в конкретном приложении может значительно отличаться в зависимости от выбранных технологий и остальных сторонних фреймворков, которые перечислены в верхней (желтой) части раздела “Клиент”. Подробное описание этих компонентов системы мы отложим как темы для будущих статей, но сравнительную таблицу я всё-таки приведу:
Back-End
Пришло время рассмотреть часть “Сервер”, потому что вряд ли найдется сколько-нибудь полезный проект (сайт, приложение), который не был бы ни коим образом связан с данными (БД). Про сквозную интеграцию говорить особо нечего, единственное, что можно упомянуть, что, так или иначе, в любом проекте есть базовые операции, как то: чтение настроек, запись настроек, файловые операция чтения/записи и другие подобного рода обобщенные операции. Модули и сервисы которые управляют этими операциями носят имя – “управление операциями”.
Что касается “безопасности”, то тут существует огромное количество вариантов реализации: авторизация и аутентификация на основе ASP.NET SimpleMembership, Microsoft Identity, Open Auth и даже собственная реализация механизмов.
По остальным составляющим “кубика” “Web-сервер” пройдемся снизу вверх. Уровень доступа к данным (DAL) имеет в себе определение “Компоненты доступа к данным”. Под этим большим понятием кроются компоненты типа ORM (например, MS EntityFramework или LLBLGen). А также компоненты “прямого” доступа к БД (например, SQLDataReader, SqlCommand или кастомные реализации на их основе).
“Утилиты” подразумевают под собой вспомогательные средства для работы с БД. Например, генераторы схем БД или генераторы кода по типу таблицы, в общем разного рода помощники для роботы с БД и ее компонентами.
К “Сервисам” можно отнести такие компоненты как SQL Report Service или сервисы по синхронизации данных, сервисы распределяющие нагрузку или другого типа сервисы, которые работают непосредственно с БД.
“Уровень бизнес-логики” – это есть “приложение”, как раз то, чем определяются задачи и функции программы (web-приложения). Бизнес-логика приложения содержит привила управления данными проходящие через программу. Уровень бизнес-логики призван решать прикладные задачи.
“Уровень представления” – самый простой для понимания раздел архитектуры, потому что он лежит на “поверхности” и его можно “пощупать мышкой” 🙂 Представления генерирующие серверной частью приложения актуальны и на сегодняшний день, но позиции такого рода подхода стремительно падают в пользу HTML5. Мне доводилось встречать приложения достаточно мощные и многофункциональные, которые были сделаны практически без использования JavaScript, но эра таких web-приложений практически сошла на нет.
Концепция web-приложения
Современные web-приложения “стремятся” к виду Desktop-приложений, но специфика работы Web стандартов, то есть асинхронная модель поведения, когда на любой Request приходится ждать Response от сервера, накладывает ряд ограничений на дизайн и, соответственно, на архитектуру приложения. Примером может быть например, обязательное требование (в описании Web 2.0) уведомление пользователя о процессе запроса. То есть, если пользователь кликнул кнопку “отправить сообщение”, то программист должен уведомить пользователя о течении процесса, показав на время ожидания ответа от сервера о результате операции картинку анимации, или вывод динамического сообщения. Понятно, что подобного рода интерфейс может быть и в Desktop-приложениях, но для Web-платформы это ключевое понятие (особенно если учесть, что на Request не всегда приходит Response).
Вариант архитектуры для Web-приложения
Наверное, пришло время рассказать, какие предпочтения и почему выбираю я. Надо отметить, что со временем были перепробованы массы различных технологий и фреймворков. Историю этих проб и ошибок можно проследить по статьям моего блога. Для простоты я приведу технологии, на использовании которых я остановился, одним списком, но список будет с комментариями.
Front-End:
- KnockoutJS – как фреймворк для связывания данных JavaScript-моделей с HTML. В ответ на очень частый вопрос “почему именно knockout” отвечаю. Принцип связывания данных у KnockoutJS построен на модели MVVM, что соответствует принципу в WPF и Silverlight, а значит мне не нужно переосмысливать базовые понятия, принципы и паттерны. Кстати сказать, AngularJS реализует принцип MVC, что не может не повлиять я внутренние концепции при реализации приложений с его использованием. OpenSource
- Для доступа к web-сервисам я использую jQuery.ajax(), иногда AmplifyJS, и совсем редко — вызовы напрямую через XMLHttpRequest. OpenSource
- Bootstrap – фреймворк для построения UI. Данный фреймворк создает адаптивную HTML-разметку, которая одинаково хорошо выглядит как на разных браузерах, так и на разных разрешениях экрана. OpenSource
- SiteJs – это набор скриптов для построения web-приложения по принципам SPA (и не только).
Back-End:
- Web API – современные решения для построения сервисов на основе RESTful. OpenSource
- EntityFramework – быстроразвивающийся ORM от компании Microsoft, который недавно стал OpenSource.
- ASP.NET MVC — как web-платформа для web-приложений. OpenSource. Альтернативой может быть node.js или Web API self-host. По сути, совершенно не важно какую web-платформу вы используете. Ключевой момент состоит в том, что HTML5 может работать на любой, а сервис предоставляющий данные для вашего приложения, может быть как платформе ASP.NET, так и на других современных платформах, вплоть до сторонних сервисов.
Заключение
На этом наверное, всё. Единственное, что стоит отметить, так это то, что каждый из вас вправе выбирать любую удобную и близкую по духу конфигурацию архитектуры приложения. В этой статье я озвучил лишь базовые понятия и основные принципы построения современного web-приложения (сайта). С другой стороны, у каждого из выбранного компонента архитектуры есть свои плюсы и минусы. Умея ловко подбирать “правильные кубики” позволит в дальнейшем: а) избежать необходимость “переделки” приложения или его частей; б) с легкостью поддерживать приложение, обновляя сборки и фреймворки на новые более производительные версии; в) идти в ногу со временем, применяя новые стандарты в программировании и дизайне.