Принципы

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

Примерами таких приложений являются CRUD-приложения, административный UI для веб-сайтов, инструменты автоматизации бизнеса, CRM-системы или системы класса ERP. Эти приложения часто предполагают управление десятками или сотнями взаимосвязанных объектов на сотнях или тысячах экранов, при этом в основном используются стандартные компоненты пользовательского интерфейса, такие как поля, формы и таблицы.

Чтобы эффективно создавать приложения такого рода, разработчикам нужен инструмент, позволяющий работать на более высоком уровне абстракции, чем тот, который обеспечивают базовые технологии, такие как Spring или Jakarta EE. Инструмент должен скрывать ненужные детали и избавлять от написания однообразного кода, поскольку такие приложения обычно содержат множество однообразных элементов: во многом похожие друг на друга сущности, атрибуты, поля пользовательского интерфейса, экраны и т.д. Но в то же время уровень абстракции не должен быть слишком высоким, чтобы позволить разработчикам описывать бизнес-логику на знакомом языке программирования и использовать современные мощные инструменты разработки - от IDE и VCS до фреймворков тестирования и CI/CD.

Задача Jmix - обеспечить адекватный уровень абстракции для разработки вышеупомянутого класса приложений.

Ниже описаны принципы, на которых Jmix основан.

Фулл-стек разработка

Jmix предлагает фулл-стек подход к разработке, который имеет два основных аспекта:

  1. Использование единого языка программирования и парадигмы разработки. Бэкенд-разработчик может реализовать бизнес-функциональность на всем стеке, от схемы базы данных до пользовательского интерфейса, при этом создавая простой синхронный Java (или Kotlin) код. Прикладному разработчику нет необходимости разбираться во фронтенд-технологиях, основанных на JavaScript.

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

Эти аспекты на самом деле следует приписать фреймворку Vaadin, который используется в Jmix под капотом. Vaadin предоставляет богатый набор UI-компонентов, каждый из которых имеет клиентскую и серверную части. Клиентская часть написана на JavaScript и работает в браузере, серверная часть написана на Java и работает на сервере. Пользователи взаимодействуют с клиентской частью компонентов, в то время как серверная часть напрямую работает с Java-кодом приложения.

principles full stack 1
Figure 1. Пример взаимодействия компонента Vaadin

Таким образом, разработчикам приложений не нужно создавать API для фронтенда и не нужно писать фронтенд-код. Они просто взаимодействуют с серверной частью компонентов Vaadin.

Если вы не знакомы с этой концепцией, мы рекомендуем прочитать статью в нашем блоге: Простота и целесообразность серверной разработки веб-интерфейса.

Единый язык программирования и парадигма разработки позволяют бэкенд-разработчикам создавать завершенные бизнес-функции, а не только их серверные части и API. Такой подход значительно повышает производительность команды и позволяет создавать продукт без необходимости инвестиций в разработку фронтенда.

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

Обратной стороной такого подхода является то, что абстрагирование от фронтенда усложняет глубокую кастомизацию пользовательского интерфейса или создание собственных UI-компонентов. Это возможно, но, как правило, сложнее, чем при непосредственном использовании фронтенд-фреймворков. Кроме того, для работы Vaadin требуется отображение состояния UI на сервере, поэтому для каждой пользовательской сессии требуется определенный объем памяти на сервере, что ограничивает вертикальную масштабируемость (однако приложение можно масштабировать горизонтально путем добавления серверов в кластер).

Таким образом, подход Jmix и Vaadin к фулл-стек разработке приносит максимальную пользу, если функциональности существующих UI-компонентов в основном достаточно для реализации решения, и глубокая кастомизация требуется только в определенных частях пользовательского интерфейса приложения. Другое условие заключается в том, чтобы количество одновременно работающих с приложением пользователей было предсказуемым и укладывалось в общий объем памяти, доступный на серверах. Оба условия обычно выполняются для корпоративных приложений, для которых предназначен Jmix.

В контексте фулл-стек разработки необходимо также затронуть тему монолитной и микросервисной архитектур.

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

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

principles full stack 2
Figure 2. Взаимодействующие монолиты

Jmix хорошо подходит для создания модульных монолитов любого размера и гранулярности.

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

Интеграция автономных прикладных сервисов в целостную информационную систему облегчается применением дополнений OpenID Connect и Универсальный REST, а также тем фактом, что Jmix полностью совместим с любым асинхронным коммуникационным решением.

Единая модель данных

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

Далее мы сравним общепринятый архитектурный подход в разработке корпоративных Java-приложений с подходом единой модели данных и определим границы, в которых последний является более подходящим.

Обычный подход в разработке современных корпоративных приложений заключается в том, чтобы иметь отдельные модели данных: одна для хранения, другая для представления и бизнес-логики. Иными словами, обычно у вас есть слой сущностей JPA (Jakarta Persistence API), отображенных на таблицы базы данных, и отдельный слой объектов передачи данных (DTO) для передачи их во фронтенд и обратно через REST-контроллеры (либо используя GraphQL или другие технологии API). В традиционном SPA-фронтенде на JavaScript также присутствуют те же DTO, представленные в формате JSON.

principles model 1
Figure 3. Общепринятый подход

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

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

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

Аргумент безопасности в пользу наличия отдельных моделей, упомянутый выше, не актуален для приложений Jmix, так как им не нужен API для создания пользовательского интерфейса. И можно легко ограничить доступ пользователей к данным: вы просто не создаете UI-компоненты для определенных атрибутов сущности, и эти атрибуты никогда не покидают серверную часть.

Вследствие этого, основной подход в приложениях Jmix заключается в работе с единой моделью данных на всех уровнях: хранения, бизнес-логики и UI. В большинстве случаев это означает использование JPA-сущностей и их атрибутов, отображающих поля базы данных. Но Jmix не ограничивает вас только моделью хранения и поддерживает также следующие сценарии:

  • Использование вычисляемых значений, реализуемых с помощью транзиентных атрибутов в JPA-сущностях.

  • Работа с источниками данных, отличными от реляционных баз данных. В этом случае модель определяется с использованием простых Java-объектов (POJO), отображаемых на внешний API или нереляционную БД.

  • Использование POJO слоя презентации, которые структурированы иначе, чем сущности модели хранения, для сложных частей пользовательского интерфейса.

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

principles model 2
Figure 4. Подход с единой моделью данных

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

В разделе Модель данных и метаданные описывается, как Jmix предоставляет единую модель данных, содержащую различные элементы, и какие возможности это дает.

Готовые решения

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

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

Jmix ориентирован на конкретную область разработки - корпоративные приложения, и по сравнению с фреймворками общего назначения, такими как Spring или Django, предоставляет больше подходящих готовых решений для этого класса приложений.

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

Использование мейнстрим-технологий

Jmix построен на базе мейнстрим-технологий (Java, Spring, JPA) и старается не изобретать велосипед. Он применяет определенную структуру и предварительные настройки к базовым технологиям, оставаясь при этом фундаментально открытым.

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

С точки зрения инструментария и методологии, разработчики могут использовать все лучшие индустриальные практики: современные фреймворки тестирования, статический анализ кода, CI/CD и системы контроля версий.

Расширяемость

Jmix создан с расчетом на расширяемость. Если что-то в платформе не удовлетворяет вашим требованиям, вы можете расширить или заменить это своим собственным решением.

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

В разделе Модульность и расширение подробно описаны возможности расширения Jmix.