TL;DR
Jmix — новое название и новый большой релиз CUBA Platform. На текущий момент Jmix находится в стадии предварительного релиза, мы планируем выпустить стабильную версию во втором квартале 2021 года. Основные изменения:
- В ядре платформы теперь будет Spring Boot
- Фреймворк будет разделен на модули (data, security, audit, и т.д.)
- Новый подход к определению модели данных
- Обновление базы данных теперь производится при помощи Liquibase
- Процесс развертывания будет основан на стандартных средствах Spring Boot. Это обеспечит лучшую интеграцию с облачными средами выполнения
Мы будем активно развивать разработку пользовательского интерфейса на ReactJS, в то же время продолжим поддержку текущего фреймворка, основанного на Vaadin.
CUBA Platform будет поддерживаться долгое время, мы также предоставим возможность миграции на Jmix через совместимый API.
Официальный сайт Jmix: jmix.io.
Обсуждение на форуме: по-английски.
Введение
Разработка CUBA началась в 2008 году. После этого мы прошли несколько очень важных этапов. Сначала это был фреймворк для внутренней разработки без документации и проработанного API. Он использовался во всей компании и позволял разрабатывать корпоративные приложения быстрее, чем без него и быстрее, чем просто на Spring за счет того, что все типовые сервисы уже были во фреймворке.
В 2015 году мы представили CUBA Platform миру, тогда ещё под закрытой лицензией. И получили очень небольшое количество пользователей, что оказалось большим разочарованием. Стало очевидно, что нужно переходить к открытому коду и менять модель распространения.
2016 и 2017 были очень плодотворными, сообщество разработчиков на CUBA значительно расширилось за то время. Это стало большим сдвигом в умах нашей команды и мы начали лучше понимать, что мы делаем правильно, а что — не очень.
В 2018-2019 мы начали разрабатывать чистый и хорошо документированный API и перевели CUBA Studio на платформу IntelliJ. Все это привело к дальнейшему расширению сообщества и, следовательно, к большей положительной обратной связи. И сейчас мы стоим на пороге очередного крупного обновления. Давайте рассмотрим подробнее, что ждет нас в 2021-м году.
Цели создания новой версии
В новой версии CUBA нам хотелось сделать следующее:
- Сделать опыт разработки ближе к наиболее популярным фреймворкам. CUBA Platform использует чистый Spring, но сейчас Spring Boot практически завоевал мир. Кроме того, можно наблюдать восхождение новых фреймворков, таких как Micronaut и Quarkus. Все они немного схожи в основных принципах: простая настройка с использованием
.properties
или.yaml
файлов, интенсивное использование аннотаций и простое добавление и конфигурация дополнительных модулей. И мы хотели, чтобы при разработке на CUBA у разработчиков был похожий опыт. - Не изобретать колесо. С 2008-го года было разработано много новых библиотек и инструментов. Сейчас они достигли зрелости и могут быть использованы для построения серьезных бизнес-приложений. И нам хотелось заменить некоторые части CUBA на надежные и проверенные библиотеки. Например, наш собственный движок для версионирования и обновления БД.
- Уменьшить размер CUBA приложений. При создании приложения с помощью CUBA Platform не всегда требуются все возможности (например, аудит). Но это всегда было частью ядра фреймворка, что приводило к созданию лишних (для конкретного случая) таблиц в БД и запуску ненужных сервисов. Таким образом, было бы неплохо иметь возможность исключения некоторых возможностей CUBA и их подключению только тогда, когда это необходимо.
- И самая главная вещь — сохранить существующий опыт и скорость разработки приложения с CUBA.
И первая вещь, с которой мы начнем...
Название
“Что означает CUBA?” — трудно сосчитать, сколько раз нам задавали этот вопрос. Честно говоря, это было всего лишь название (не очень короткое и не очень длинное), данное одному из первых пакетов нашего внутреннего фреймворка в далеком 2008-м году. Если вы покопаетесь в исходниках ядра CUBA, вы также найдете пакеты “chile” и “bali”.
В 2021 мы меняем название. “CUBA” становится “Jmix”ом. Это имя значительно проще объяснить: “J” — это “Java”, а “mix” — технологии и фреймворки, смешанные в одном приложении. Меньше вопросов, и никаких ассоциаций ни с известным всем островом, ни со знаменитым коктейлем.
Фактически, Jmix — это следующее большое обновление CUBA с известными API, знакомым подходом к разработке и, безусловно, набором удобных инструментов и генераторов кода.
Переименование — немаловажная вещь, которая отражает большие изменения, внесенные в...
Ядро фреймворка
В широком смысле, в CUBA мы копировали некоторые подходы, принятые в Spring Boot. В итоге мы сделали собственное хранилище сессий, подсистему безопасности, авторизации и, конечно же, развертывание. А модули CUBA появились в ответ на стартеры Spring Boot с их системой инкапсуляции и автоконфигурации.
Когда мы начинали разработку CUBA в 2008, мы использовали “чистый” Spring в ядре фреймворка. Теперь в ядре Jmix мы будем использовать Spring Boot.
Использование Spring Boot дает нам следующие преимущества:
- Лучший опыт разработки. Сейчас практически каждый Java разработчик знаком со Spring Boot. C Jmix опыт разработки на Spring Boot может быть полностью использован в полной мере, нет нужды учить новый фреймворк, только несколько дополнительных модулей.
- Что касается модулей: если ядро основано на Spring Boot, то можно использовать практически все готовые стартеры. Таким образом, мы можем положиться на существующую инфраструктуру и огромное сообщество, а также — на большое количество документации и готовых решений.
- И ещё одна вещь — у Spring Boot есть великолепные возможности по части развертывания и поддержки контейнеров прямо “из коробки”. Можно не изобретать колесо.
Когда мы говорим о стартерах Spring Boot, это ведет к обсуждению ещё одной вещи…
Модульность
Время от времени нам делают замечание, что “пустое” CUBA приложение, в котором нет ни одной строчки бизнес-логики, создает слишком много таблиц в базе данных и содержит множество сервисов, которые, возможно, никогда и не будут использованы.
В 7 версии фреймворка мы начали переносить функциональность из ядра в отдельные компоненты. И этот процесс мы довели до логического завершения в Jmix.
В этом фреймворке вы можете использовать различные сервисы (аудит, безопасность и т.д.) отдельно и практически независимо друг от друга. Все эти сервисы теперь предоставляются в виде Spring Boot стартеров. Например, в CUBA есть функциональность аудита, которая теперь выделена в отдельный модуль. И этот модуль, в свою очередь, разделен на два модуля: “Core” и “UI”. Это означает, что теперь вы можете использовать функциональность аудита как целиком, так и только в виде движка, а пользовательский интерфейс для него можете создать сами.
Какая-то функциональность, например, проверка состояния приложения (healthcheck) заменена на стандартный модуль Spring Boot (смотри раздел “не изобретать колесо”).
Jmix предоставляет порядка 20 стартеров. В таблице ниже можно посмотреть некоторые из них, а также зависимости:
Функциональность | Стартер | Зависит от |
---|---|---|
Entity log | Audit | Data |
File storage | Core | |
User settings | UI Persistence | Data |
Table presentations | UI Persistence | Data |
Entity log | Audit UI | Audit, UI |
Config properties stored in DB | Core | |
Restore deleted entities | Data tools | Data, UI |
User sessions | Core | |
Dynamic attributes | Dynamic attributes | Data, UI |
Entity Snapshots | Audit | Data |
Related entities | Advanced Data Operations | Data, UI |
Bulk editor | Advanced Data Operations | Data, UI |
Как видно, стартер “data” используется практически всеми модулями Jmix. И это неудивительно, потому что одна из самых сильных сторон CUBA — это...
Слой доступа к данным
Здесь будет большое количество изменений. Мы постарались сохранить те преимущества, которые были в CUBA и добавили новые возможности для повышения продуктивности.
В CUBA Platform большое влияние уделялось метамодели — информации о классах-сущностях. Это использовалось и в runtime, и в design-time, например, для построения предикатов для ограничения данных или для привязки полей сущностей к элементам UI. Наличие метамодели позволяет проделывать разные хитрые трюки с извлечением данных: начиная от упомянутых предикатов, генерируемых в рамках подсистемы безопасности, заканчивая наличием универсального компонента для фильтрации в UI.
При всех её преимуществах, модель данных CUBA обладала одним фундаментальным неудобством: она достаточно жесткая. Например, при построении метамодели мы полагались на то, что сущность должна реализовывать интерфейс Entity
. Если вам нужно логическое удаление (a.k.a soft delete), то нужно имплементировать интерфейс SoftDelete
или наследоваться от класса BaseEntity
. А также нужно создать столбцы с предопределенными именами в таблице, связанной с сущностью.
Или, например, первичный ключ. Он должен сохраняться в столбце id
, если используется класс StandardEntity
.
Это приводило (и приводит) к ограничениям при разработке модели данных, а также создает проблемы при создании CUBA приложений, если используется существующая модель данных, как это случается в случае использования CUBA для миграции приложений с устаревших фреймворков.
В Jmix модель создания сущностей становится более гибкой. Больше не нужно наследоваться от StandardEntity
или реализовывать интерфейс Entity
. Просто добавьте аннотацию @JmixEntity
к классу, чтобы фреймворк начал с ним работать. Это нужно не только для JPA entitites, но и для случая, если вы захотите редактировать DTO в UI. Jmix Studio поможет с генерацией заготовки для экрана, а в runtime Jmix будет отслеживать изменения объектов и формировать список тех, которые были изменены. Это сильно облегчает работу по генерации операторов для вставки/обновления/удаления данных в случае использования DTO.
Также мы решили упразднить интерфейсы, которые задают функциональность сущностей. Например, мы используем аннотацию @Version
из JPA и @CreatedBy
из Spring Boot вместо собственных интерфейсов Versioned
и Creatable
.
Это делает код более наглядным — можно сразу сказать, какая функциональность поддерживается сущностью, просто взглянув на её исходник.
@JmixEntity
@Table(name = "CONTACT")
@Entity(name = "Contact")
public class Contact {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private Long id;
@Version
@Column(name = "VERSION", nullable = false)
private Integer version;
@InstanceName
@NotNull
@Column(name = "NAME", nullable = false, unique = true)
private String name;
@LastModifiedBy
@Column(name = "LAST_MODIFIED_BY")
private String lastModifiedBy;
@Temporal(TemporalType.TIMESTAMP)
@LastModifiedDate
@Column(name = "LAST_MODIFIED_DATE")
private Date lastModifiedDate;
“CUBA Views” теперь называются “Fetch Plans” — “планы выборки”. Новое имя более точно описывает назначение этого механизма.
Слой доступа к данным Jmix теперь поддерживает автоматическую ленивую загрузку ссылочных данных. Таким образом, даже если вы не будете использовать планы выборки для выборки ссылочных данных, вы никогда больше не получите ненавистное UnfetchedAttributeException
. Естественно, что ленивая загрузка может сказываться на производительности. Как раз для этих случаев и можно применять планы выборки, которые точно описывают, какие атрибуты нужны.
Ещё одним большим изменением будет другой процесс генерации и обновления базы данных. Мы решили использовать Liquibase вместо собственного движка обновления базы. За запуск скриптов будет отвечать Spring Boot. Это ещё один пример принципа “не изобретать колесо” — использование известного и проверенного движка с хорошей документацией.
Для Liquibase мы сохраним старую добрую магию CUBA: если вы меняете сущность, Jmix Studio будет генерировать Liquibase скрипт, отражающий изменения. Так что вам не придется писать диффы руками. С другой стороны, сгенерированные скрипты всегда можно поправить, Jmix не сломается из-за этого.
О чем мы ещё думаем, когда мы говорим о CUBA? Конечно, о подсистеме, которая обеспечивает...
Безопасность
В Jmix система безопасности будет поставляться отдельным модулем. Теперь вы выбираете, хотите вы использовать подсистему от CUBA или свою собственную.
Теперь подсистема безопасности тесно интегрирована со Spring Security. Для того, чтобы облегчить жизнь разработчикам и продолжать следовать принципу “не изобретать колесо”, мы заменили наш код на вызовы “стандартной” библиотеки. У Spring Security превосходная документация, и эта библиотека хорошо знакома разработчикам. Модель данных системы безопасности поменялась в соответствии с этим: в Jmix мы используем классы из Spring Security, такие как UserDetails
и SessionRegistry
, для опытных CUBA разработчиков это может быть поначалу немного непривычно.
Роли тоже поменялись — мы объединили роли и группы доступа, чтобы упростить управление безопасностью. В дополнение к этому мы добавили “объединяющую” роль. Она составляется из нескольких ролей — мы получали большое количество запросов от пользователей по поводу реализации этой функциональности.
Spring Security — не самая простая вещь в использовании и настройке, но в Jmix мы сделали этот процесс настолько простым, насколько возможно. Вы можете настраивать доступ к сущностям, атрибутам, экранам, а также настраивать безопасность на уровне строк БД, как это было в CUBA.
И, как это было в CUBA, все, что будет нужно, чтобы добавить подсистему безопасности в ваше приложение — это просто добавить зависимость в свой проект, а уж Jmix сделает все остальное. У вас будет установленная и настроенная система безопасности с экранами управления (если захотите).
Кроме подсистемы безопасности есть ещё одна вещь, которая нравилась почти всем, кто использовал CUBA — простота создания такой важной части приложения, как...
Пользовательский интерфейс
Generic UI на основе Vaadin остается. Компонентная модель построения пользовательского интерфейса была большой частью CUBA, и мы планируем поддерживать ее и в Jmix.
Будут поддерживаться генераторы экранов, визуальный редактор интерфейса и т.д. Мы добавили новые компоненты: отдельный виджет для постраничной навигации и ResponsiveGridLayout
для размещения компонентов. Одно важное отличие — теперь можно исключить Generic UI из приложения полностью благодаря модульной архитектуре Jmix.
Нужно заметить, что теперь все Jmix-приложения будут Single-tiered. Этот подход сильно упрощает архитектуру и развертывание, а ещё — нужно меньше кода и меньше проблем с detached сущностями.
Если вам нужно разделение на фронт и бэк, можно сделать два Jmix приложения и создать REST API для коммуникации между ними. В этом случае фронт не будет зависеть от модели данных, а вы будете передавать DTO объекты для отображения данных в интерфейсе и для их обработки алгоритмами бизнес-логики, как, собственно, все сейчас и делают.
Когда мы планировали разработку новой версии нашего фреймворка, то не могли проигнорировать заметный рост JavaScript фреймворков для разработки пользовательского интерфейса. Мы начали разработку генераторов для создания экранов с использованием ReactJS — это был front-end
модуль в CUBA 7. И мы продолжим эту работу в Jmix. JS фреймворки довольно непросты в освоении, наша цель — сделать ReactJS разработку настолько близкой к разработке Generic UI, насколько это возможно.
Мы создали TypeScript SDK и разработали набор собственных ReactJS компонентов, которые могут быть использованы для разработки пользовательского интерфейса.
Среда разработки поддерживает генерацию простых экранов на ReactJS. Сейчас разработчик может создавать экраны для просмотра, выбора и редактирования сущностей. Позже мы планируем добавить ещё больше компонентов и создание визуального редактора UI в Jmix Studio.
Мы обсудили почти все нововведения в Jmix. Но будет нечестно забыть про…
Развертывание
В CUBA было два формата развертывания: WAR и UberJar, и два варианта: единым приложением или раздельно (core+web+...).
Jmix будет использовать возможности Spring Boot для развертывания. Это означает, что мы можем запускать Jmix приложение как исполняемый JAR файл или развертывать WAR (можно его также запустить как отдельное приложение).
Но самое лучшее здесь — поддержка контейнеров. Теперь не нужно создавать собственный Docker файл для создания образа приложения, генерация такого файла поддерживается “из коробки”. Также можно создавать многослойные JAR файлы для более эффективного использования Docker образов. И, кроме того, поддерживаются cloud-native buildpacks, позволяющие ещё больше упростить создание образа для контейнера.
Таким образом, Jmix приложения будут поддерживать последние достижения в области контейнеризации и выполнения в облачных средах.
Вы можете подумать: “Столько изменений. А как же такая важная тема, как...”
Миграция с CUBA на Jmix
Первое: мы не бросаем CUBA. Версия 7 будет на долговременной поддержке следующие пять лет. И после этого ещё пять лет будет доступна коммерческая поддержка. Итого, десять лет поддержки для CUBA.
На текущий момент Jmix находится в стадии предварительного просмотра, мы продолжаем его стабилизировать и планируем анонсировать стабильную версию в конце первого полугодия 2021. Но если вы планируете начать разработку на CUBA прямо сейчас, сначала присмотритесь к Jmix. Он достаточно стабилен, чтобы на нем можно было делать прототипы и решать, подойдет вам фреймворк или нет, чтобы начать его использовать, когда выйдет стабильная версия. И помните, что в случае Jmix к вашим услугам почти вся экосистема Spring Boot.
Для обеспечения обратной совместимости мы сделали специальный модуль — jmix-cuba
. Этот модуль содержит большинство API CUBA, так что вам не нужно будет сильно менять свой код при миграции на следующую версию фреймворка. Модуль совместимости будет добавлен автоматически к приложению в процессе миграции.
Большинство компонентов CUBA будет постепенно переведено на платформу Jmix: отчетность, карты, управление бизнес-процессами. И так же, как мы делали в CUBA 7 раньше, часть компонентов может быть объявлена устаревшими, потому что в Spring Boot уже есть такая функциональность.
Формат компонентов поменялся, теперь это стартеры, но функциональность остается такой же. Вы можете расширять сущности и экраны, используя те же техники, что и в CUBA. Что касается переопределения сервисов, то здесь используется подход Spring Boot — просто отметьте свой сервис аннотацией @Primary
и сервис будет заменен.
Как обычно, при объявлении новой версии (Jmix, фактически, это CUBA 8), обязательно будут “ломающие” изменения. Они все будут задокументированы, и мы предоставим инструкции по их реализации.
Большая часть миграции — это новая Jmix Studio. Этот инструмент играет ключевую роль в экосистеме Jmix. Вы сможете использовать знакомые визуальные редакторы, сочетания клавиш и подсказки для кода. И, как обычно, Jmix Studio будет помогать вам в создании приложений при помощи генераторов кода, быстрой навигации и прочих своих инструментов.
Заключение
Jmix — это большой шаг в развитии CUBA. Теперь вам доступны почти все Spring Boot библиотеки и приемы разработки, применимые для разработки современных приложений с использованием одного из самых популярных фреймворков в мире. При этом у вас есть все те же знакомые API, функциональность и набор инструментов, которую предоставлял фреймворк CUBA Platform.