Pull to refresh
97.14
Haulmont
Создаем современные корпоративные системы

Vaadin Flow — диковинный олень

Reading time 9 min
Views 21K
Всякая перемена, даже перемена к лучшему,
всегда сопряжена с неудобствами

Ричард Хукер

Как вы возможно знаете, Vaadin — один из самых популярных web-фреймворков на Java:


Совсем недавно вышел новый релиз этого фреймворка для разработки web UI — Vaadin 10. Про Vaadin 10 и Vaadin Flow пока довольно мало публикаций на русском, и этот пост призван восполнить этот пробел.


Создатели позиционируют Vaadin Flow как новый Java web-фреймворк для разработки современных web-приложений и web-сайтов (вот тут я им не совсем верю). Это часть Vaadin Platform, которая приходит на замену другому продукту — Vaadin Framework, она позволяет разрабатывать web-приложения (а если быть точным, то web UI) с применением стандарта Web Components на Java.

Тут у читателя в голове скорее всего всё уже смешалось, все эти Vaadin Bla Bla, фреймворк, платформа и прочее. Что происходит?

Мы используем Vaadin в составе своей платформы CUBA для UI back-office систем на протяжении 7 лет и за это время накопили большой опыт работы с ним, поэтому нас не может не волновать его судьба. Под катом вы найдёте мои спекуляции на тему Vaadin 10.

Vaadin Framework


Vaadin — это финская компания, которая разрабатывает инструменты и библиотеки для разработки UI. Они же делают одноимённый фреймворк для web-разработки на Java.

Vaadin Framework — это UI фреймворк с server-side моделью программирования, в которой вся логика UI и его состояние расположены на сервере, а в браузере исполняется только код UI компонентов. По сути, это технология тонкого клиента, где браузер всего лишь отображает то, что скажет сервер, а все события отправляются на сервер.

Server-side подход позволяет забыть про то, что разработка ведется под web, и разрабатывать UI как настольное Java-приложение с непосредственным доступом к данным и сервисам на сервере. При этом Vaadin позаботится и о отображении UI в браузере, и об AJAX-взаимодействии между браузером и сервером. Движок Vaadin осуществляет рендеринг пользовательского интерфейса приложения серверной стороны в браузере и реализует все детали обмена клиента и сервера.



У этого подхода есть много плюсов:

  • Java код проще писать и отлаживать
  • Можно использовать существующие Java библиотеки и инструменты (IDE, компиляторы, тестирование)
  • Не требуется разрабатывать веб-сервисы
  • Лучше обстоят дела с безопасностью

И минусов:

  • Нужно много памяти на сервере для UI представления
  • Сложнее масштабировать решение
  • При разработке виджетов требуется разрабатывать Java API

Исходя из этих минусов и плюсов Vaadin FW плотно поселился именно в enterprise разработке, где нагрузки предсказуемы, а скорость и простота разработки гораздо важнее стоимости железа и памяти.

Что случилось с Google Web Toolkit


Всё то время, что Vaadin знаком широкой публике, клиентская часть Vaadin FW была неразрывно связана с другим известным продуктом — Google Web Toolkit (GWT). Этот тандем позволял писать сами UI компоненты и серверный API для них на одном языке — Java, что было довольно удобно.

Последние годы Google Web Toolkit не развивался, и мы с 2015 года всё ждём появления GWT 3.0 / J2CL, анонсированного на GWT.Create 2015:


В этот застойный период (2015-2017) случилось важное событие: появилась спецификация Web Components и другой фреймворк от Google — Polymer. Видимо, это и послужило началом конца GWT.

Стоит отметить, что GWT 3 разрабатывается как внутренний фреймворк Google и его разработка ведется внутри компании. А значит, коммьюнити никак не может влиять на процесс или хотя бы видеть, что процесс идёт.

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

Web Components


Web Components — это набор стандартов. Его предложили и активно продвигают ребята из Google, но инициативу уже поддержали в Mozilla. По сути, это технологии для создания UI компонентов для web, так, чтобы в них поддерживалась инкапсуляция поведения и представления. А главный плюс — возможность повторного использования.

Основные концепции:

  • Custom Elements — API для создания своих HTML элементов
  • Shadow DOM — инструмент инкапсуляции HTML компонентов и изоляция их визуального представления от глобальных правил CSS. Если коротко, то вы можете сделать компонент, например, форму заказа, и не бояться, что её стили сломаются на какой-то из страниц сайта из-за CSS правил этой страницы.
  • HTML Templates — возможность размещения в HTML документе пассивных блоков, содержащих DOM элементы-заготовки. Такие блоки парсятся браузером, но не отрисовываются и не исполняют свой код. Их предлагается использовать в качестве шаблонов для рендеринга данных.
  • HTML Imports — возможность импортировать HTML документ как модуль со всей его версткой, стилями и JS

Например, если сейчас заглянуть в DOM дерево YouTube, то вы обнаружите использование Custom Elements и Shadow DOM:



Все эти штуки и позволяют писать новые модные UI компоненты для web.

Тут стоит признаться, что поддержка в браузерах далека от совершенства и все еще требуются полифилы, например для Edge.

Polymer


Polymer — это небольшая библиотека поверх стандартов Web Components, призванная упростить их использование. Пример:

// Импортируем существующие компоненты
import '@polymer/paper-checkbox/paper-checkbox.js';
import {PolymerElement, html} from '@polymer/polymer';

// Определяем новый класс
class LikeableElement extends PolymerElement {

  // Здесь будут публичные свойства компонента
  static get properties() { return { liked: Boolean }}

  // Так будет выглядеть DOM дерево внутри, CSS влияет только на сам компонент
  static get template() {
    return html`
      <style>
        .response { margin-top: 10px; } 
      </style>
      <paper-checkbox checked="{{liked}}">I like web components.</paper-checkbox>

      <div hidden$="[[!liked]]" class="response">Web components like you, too.</div>
    `;
  }
}
// Регистрируем элемент в браузере
customElements.define('likeable-element', LikeableElement);

По сути, Polymer делает всё то, что раньше делал GWT, но при этом он совместим с любыми JS компонентами и другими фреймворками, например, React и Angular.

Vaadin Components


Вернёмся к Vaadin. Довольно давно компания Vaadin делает продукт под названием Vaadin Components — UI компоненты для фронтенд разработчиков, которые могут встраиваться в любые JS приложения.



Эти компоненты базируются на Web Components и Polymer!

Как мы теперь видим, это был запасной аэродром для Vaadin Framework, позволивший уйти от Google Web Toolkit и разработать новый фреймворк, для которого еще не существовало компонентов. Проблема курицы и яйца решена и Vaadin Components стали фронтендом грядущего Vaadin 10.

Vaadin Flow


Vaadin 8 включал в себя механизм синхронизации состояния UI и поддержку двустороннего RPC протокола (удаленного вызова процедур). Это было возможно благодаря GWT, поскольку общие интерфейсы и классы сервера и клиента писались на Java.

Вместе с отказом от GWT потребовалось реализовать новый механизм, который бы позволил прозрачно интегрироваться с JS фронтендом и Java бэкендом. Этим механизмом стал Vaadin Flow (а ещё это имя долгое время использовали для обозначения всего Vaadin 10).

В документации по Flow есть такая схема:



Основной её смысл в следующем:

  • поддерживается синхронизация состояния UI с сервера на клиент
  • серверная часть может подписываться на события UI компонентов, при этом будет выполнен AJAX запрос
  • бизнес-логика выполняется на сервере, в веб-браузер загружаются только данные, отображающиеся в UI
  • серверная часть использует Java
  • клиентская часть может использовать HTML, CSS, JS и шаблоны Polymer

Для меня это означает, что в Vaadin станет больше фронтенд технологий, а теперь одной Java явно недостаточно (для Vaadin 8 вам хватило бы Java и не требовались HTML/CSS). С другой стороны, теперь возможна легкая интеграция JS кода.

Vaadin Platform


Каждый компонент Vaadin 10 разрабатывается отдельно и в лучших традициях JS мира — крошечные модули, максимально независимые друг от друга. При этом клиентская часть компонентов упакована в JAR в формате WebJARs: www.webjars.org

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



Чтобы хоть как-то управлять этим хаосом появился проект BOM (Bill of Materials) под названием Vaadin Platform.

Это не какой то самостоятельный продукт, а всего лишь список совместимых версий компонентов и инструментов оформленный в формате Maven BOM.

Подключается в Maven он следующим образом:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-bom</artifactId>
            <version>${vaadin.platform.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Возможности Vaadin 10


Итого, весь фреймворк состоит из 3х составляющих:

  1. Vaadin Components — фронтенд
  2. Vaadin Flow — транспорт
  3. Server Components API — Java API для UI компонентов

Начинать его освоение стоит с официального туториала.

Также, рекомендую свежий вебинар.

Starters


Более плотно познакомиться с фреймворком можно со страницы. Там вы найдёте примеры проектов, в том числе full-stack на базе Spring Boot.

Ярые поклонники Spring Boot могут проследовать прямо в start.spring.io и выбрать там Vaadin среди web-фреймворков.

Минимальный проект можно начать с одного Java класса, например:

// определяем URL для страницы
@Route("")
public class MainView extends VerticalLayout {

    public MainView() {
        // конструируем UI из компонентов
        Button button = new Button("Click me");
        // подписываемся на события
        button.addClickListener(event -> {
            new Notification("Hello!").open();
        });

        add(button);
    }
}

В общем и целом, можно писать на Vaadin 10, как на Vaadin 8, НО! Нужно обязательно заглянуть на страницу соответствия компонентов.

Element API


Киллер фича Vaadin 10 — управление элементами DOM прямо из серверного Java кода.

Element nameField = ElementFactory.createInput();
nameField.setAttribute("id", "nameField");
nameField.setAttribute("placeholder", "John Doe");
nameField.setAttribute("autofocus", "");

Также можно управлять атрибутами, которые уже проставлены:

// "John Doe"
String placeholder = nameField.getAttribute("placeholder");
// true
nameField.hasAttribute("autofocus");
nameField.removeAttribute("autofocus");
// ["id", "placeholder"]
nameField.getAttributeNames().toArray();

Конечно же, это не замена UI компонентам, но хороший API для простых изменений верстки, когда разработка UI компонентов не требуется.

Data binding


Для работы с компонентами, реализующими интерфейс HasValue (get/set value и ValueChangeListener) есть удобный класс Binder:

Binder<Person> binder = new Binder<>();
TextField titleField = new TextField();

binder.forField(titleField)
  .bind(
    Person::getTitle,
    Person::setTitle);

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

Кроме того, биндинг может устанавливать конвертеры значений и валидаторы:

binder.forField(yearOfBirthField)
  // Validator will be run with the String value of the field
  .withValidator(text -> text.length() == 4,
    "Doesn't look like a year")
  // Converter will only be run for strings with 4 characters
  .withConverter(
    new StringToIntegerConverter("Must enter a number"))
  // Validator will be run with the converted value
  .withValidator(year -> year >= 1900 && year < 2000,
    "Person must be born in the 20th century")
  .bind(Person::getYearOfBirth, Person::setYearOfBirth);

Templates


HTML шаблоны представляют собой вёрстку вида:

<link rel="import" href="../bower_components/polymer/polymer-element.html">
<link rel="import" href="../bower_components/paper-input/paper-input.html">

<dom-module id="hello-world">
    <template>
        <div>
            <paper-input id="inputId" value="{{userInput}}"></paper-input>
        <button id="helloButton" on-click="sayHello">Say hello</button>
        <div id="greeting">[[greeting]]</div>
    </div>
    </template>
    <script>
        class HelloWorld extends Polymer.Element {
                static get is() {
                    return 'hello-world'
                }
        }
        customElements.define(HelloWorld.is, HelloWorld);
    </script>
</dom-module>

В шаблонах поддерживается декларативный биндинг данных и можно писать нативный JavaScript, который будет исполняться в браузере as-is. Это позволяет реализовывать часть простейшей UI логики без отправки запросов на сервер.

Events


Обработка событий компонентов делается очень просто:

TextField textField = new TextField();
textField.addChangeListener(e -> System.out.println("Event fired"));

Здесь вы не заметите разницы с Vaadin 8.

Routing


Навигация и роутинг в приложении стали такими какими должны быть:

@Route("some/path")
public class SomePathComponent extends Div {
  public SomePathComponent() {
    setText("Hello @Route!");
  }
}

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

Разработка компонентов


Для Vaadin 10 можно разрабатывать компоненты следующими способами:


Такой прямолинейный подход в разработке custom-компонентов, пожалуй, самый большой шаг вперёд. Больше не требуется писать обёртки для JS на GWT, чтобы затем писать серверную часть на Vaadin.

Lumo Theme


Вместо SASS для визуальных тем теперь используются CSS Variables, т.е. больше не требуется компилировать CSS при сборке проекта:

<custom-style>
    <style>
        html {
          --lumo-font-family: "Open Sans", sans-serif;
        }
    </style>
</custom-style>

А на смену теме Valo приходит новая настраиваемая тема Lumo.



Миграция с Vaadin FW 8


Опции миграции с Vaadin 8 описаны в документе: vaadin.com/docs/v10/flow/migration/1-migrating-v8-v10.html

Тут у меня для вас плохая новость: если вы написали огромный проект на Vaadin 8, то вам потребуется его полностью переписать при переходе на Vaadin 10. Пути миграции нет, от слова совсем!

Vaadin 10 и Vaadin 8 похожи в нескольких аспектах:

  • Server-side подход
  • Java для разработки логики UI
  • Одинаковый подход к биндингу данных

В сухом остатке: Vaadin 10 это новый фреймворк написанный с нуля.

Как обещают разработчики, Vaadin 8 будет поддерживаться до 2022 года, возможно появятся подходы к миграции.

Заключение


Считаю важным тот факт, что новый веб-сайт компании Vaadin написан на Vaadin Flow, что становится де-факто стандартом для фронтенд технологий, как в своё время зрелость языка программирования определялась тем, написан ли его компилятор на этом же языке.

Надеюсь, что теперь и вы сможете составить свое мнение о Vaadin 10. В целом, это неплохой фреймворк и огромный задел на будущее. Для меня же — это отличный экспериментальный полигон для новых идей и подходов к построению UI.
Tags:
Hubs:
+19
Comments 8
Comments Comments 8

Articles

Information

Website
www.haulmont.ru
Registered
Founded
Employees
501–1,000 employees
Location
Россия
Representative
Haulmont