Мы рады сообщить о выходе нового релиза платформы CUBA и CUBA Studio! Пожалуй, этот релиз – один из самых богатых на новшества в истории платформы. Важные изменения коснулись всех уровней: архитектуры платформы, её расширяемости, удобства API и производительности.
В этой статье мы расскажем об основных улучшениях платформы. Полный список изменений доступен здесь:
Platform 6.3 Release Notes
Studio 6.3 Release Notes
Contents
Компоненты приложения
Поддержка нескольких хранилищ
Базовые классы сущностей
Технология единого входа
Анонимное использование
Новый REST API
Screen Agent
Кэш запросов
Компоненты уровня приложения
Платформа с самых первых версий поддерживала механизм функциональной декомпозиции: с одной стороны, сама платформа разделена на ядро и дополнения, с другой, можно было создавать расширения проекта приложения. Механизм расширений был ограничен тем, что работал только вертикально – была возможность создать несколько расширений одного базового проекта, но не было возможности создания дополнений, таких как CUBA Reporting или BPM, которые можно комбинировать с другими дополнениями в готовом приложении и переиспользовать в других проектах.
Мы решили эту проблему, добавив концепцию Компонентов приложения. В рамках этой концепции вы можете декомпозировать большое приложение на набор функциональных модулей и разрабатывать их как отдельные проекты. Более того, эти модули можно использовать повторно – вы можете подключать их к разным приложениям так же, как премиум-дополнения CUBA.
Например, в приложении для управления парком такси структура компонентов может выглядеть так:
Здесь CUBA, Reports и Full-Text Search – компоненты, предоставляемые платформой; Credit Card Payments и Pricing – переиспользуемые компоненты, подключаемые к разным приложениям, Driver Wages – дополнительная функциональность, доступная только определённым клиентам. Наличие такой опциональной зависимости говорит о том, что вы можете добавлять компоненты приложения не только на стадии разработки, но и на этапе развертывания.
На самом деле, компонент приложения (или app component) – это просто приложение, предоставляющее некоторую информацию о своем устройстве. Информация о модулях, параметры конфигурации и артефакты компонента содержатся в отдельном файле: app-component.xml; по специальным записям в манифесте JAR происходит автоматическое обнаружение компонентов, находящихся в classpath. Компоненты приложения можно также рассматривать как full-stack библиотеки: они предоставляют функциональность на всех уровнях, включая сущности, скрипты баз данных DDL, сервисы среднего слоя, экраны UI и даже темы на CSS.
Studio позволяет автоматически генерировать app-component.xml для текущего проекта, если вы хотите сделать его компонентом. Для этого достаточно воспользоваться ссылкой на вкладке Project properties. Чтобы использовать некоторый компонент в приложении, откройте на редактирование Project properties и добавьте компонент в список Custom components.
Пример создания и использования компонентов уровня приложения вы можете найти в документации.
Поддержка нескольких хранилищ
До сегодняшнего дня механизмы платформы поддерживали использование в приложении только одной базы данных. Использовать другие источники данных напрямую через JDBC было возможно, но реализовать отображение и редактирование этих «внешних» данных в стандартных компонентах UI было слишком сложно.
Концепция хранилищ данных, появившаяся в CUBA 6.3, разработана для решения проблемы работы с данными из различных источников в одном приложении через стандартные механизмы платформы, такие как data-aware визуальные компоненты. По сути, хранилище – это интерфейс с несколькими методами загрузки и сохранения сущностей. Сейчас платформа содержит единственную реализацию этого интерфейса, позволяющую работать с реляционными базами данных, используя слой ORM. Вы можете создавать свои собственные реализации хранилищ данных в ваших проектах, к примеру, для работы с NoSQL базами, распределёнными in-memory grids, или для интеграции с другими приложениями.
Когда в приложении используется несколько хранилищ, его модель данных будет содержать сущности, связанные с данными из нескольких мест. Если хранилище данных представляет собой RDBMS, классы сущностей будут иметь аннотации персистентных классов JPA. В противном случае, сущности будут неперсистентными, и маппингом сущностей на данные должно заниматься ваше кастомное хранилище. У приложения всегда будет одно «главное» хранилище, подключенное к RDMS, для хранения сущностей платформы, таких как Пользователи, Роли, Фильтры и т.д. Сущности же приложения могут быть разбросаны по неограниченному количеству различных хранилищ.
К примеру, на схеме ниже представлена структура хранилищ данных гипотетического приложения, интегрированного на уровне БД с ERP-системой, использующего MongoDB для хранения документов и REST API для подключения к удалённой информационной системе. Нативные элементы CUBA окрашены зелёным, жёлтые блоки – элементы, разработанные на уровне приложения.
Смешанная модель данных и специальные хранилища открывают путь к созданию микросервисов (или, если точнее, Self-Contained Systems). Предположим, у вас есть приложение Sales, обладающее функциональностью для управления покупателями (Customers) и продуктами (Products). Вы можете разделить приложение на три независимых проекта: Sales, Customers и Products, каждый со своей собственной базой данных и своим UI. В приложении Sales вы создаёте два дополнительных хранилища данных для интеграции с другими приложениями. В простейшем случае, хранилища могут быть встроенным RdbmsStore, так что Sales будет напрямую подключаться к чужим базам данных. Для более слабого связывания вы можете создать отдельные хранилища через REST API и отобразить удалённые данные на неперсистентные сущности модели данных Sales. В результате вы получите три относительно небольших самодостаточных приложения: Customers и Products работают сами по себе, Sales содержит бизнес-логику и UI, основанный на стандартных механизмах CUBA, но при этом использующий данные удалённых систем.
Сущности из разных хранилищ пока не могут иметь прямых связей. Это значит, что если вам нужно создать ссылку на сущность из другого хранилища, вы должны создать персистентный атрибут для ID «внешней» сущности и неперсистентный атрибут для самой сущности, и управлять загрузкой и сохранением этих атрибутов программно. В будущих релизах платформы мы планируем предоставить возможность простого декларативного связывания сущностей на уровне приложения.
Используя Studio, вы можете легко настроить дополнительные хранилища данных (RDBMS или специальные) на вкладке Advanced страницы Project properties.
Для более полной информации о подключении хранилищ вы можете ознакомиться с документацией.
Базовые классы сущностей
Мы провели рефакторинг базовых классов сущностей, чтобы сделать их более легковесными. Теперь минимальная сущность может иметь только один обязательный системный атрибут – id, который может быть связан с колонкой БД практически любого типа, включая IDENTITY. Кроме того, теперь есть поддержка составных ключей.
Это значит, что вы можете создавать сущности CUBA для практически любой базы данных, не меняя ее схему. Так, к примеру, новое CUBA-приложение может работать с устаревшей БД параллельно со старой системой. Кроме того, вы можете интегрироваться со сторонними системами путём подключения их баз как дополнительных хранилищ данных.
Технология единого входа
Технология единого входа (Single Sign-On, SSO) для CUBA-приложений позволяет пользователю входить в несколько запущенных приложений, введя логин и пароль один раз в течение сессии браузера. Единый вход обеспечивает бесшовную работу пользователя сразу с несколькими системами. Он также позволяет администраторам системы управлять паролями пользователей в одном месте, даже если интеграция с LDAP не используется.
CUBA SSO не требует усилий для настройки, так как любое CUBA-приложение может выступать как Identity Provider (IDP), который является центральным элементом инфраструктуры SSO. Конфигурация может быть настроена на стадии развертывания, так что вам не нужно беспокоиться об этом в процессе разработки приложений.
Схема демонстрирует систему SSO для двух приложений. App 1 является одновременно Identity Provider и Service Provider (т.е. обычным приложением с некоторой функциональностью). Оно содержит особую форму логина, отображаемую всем пользователям системы SSO. App 2 выступает как Service Provider, перенаправляющий пользователей в App 1 IDP для логина. Пароль пользователя проверяет только IDP, однако роли и разрешения пользователей настраиваются полностью независимо.
Более подробная информация о Single Sign-On находится в документации.
Анонимное использование
Теперь некоторые экраны UI в вашем приложении могут быть доступны без логина. В платформе появился предопределенный «анонимный пользователь», и весь код приложения, работающий до логина, исполняется от имени этого пользователя. По умолчанию у анонимного пользователя есть все разрешения, так что не забудьте создать для него роль с только необходимыми правами перед тем, как разрешить анонимный доступ в вашем приложении.
Как это работает: в любом приложении есть два окна верхнего уровня: окно логина и главное окно. Первое работает для анонимного пользователя, второе – для аутентифицированного пользователя. По умолчанию окно логина содержит только форму логина, но вы можете добавить к нему любые визуальные компоненты и источники данных, или даже элементы главного окна, такие как WorkArea, чтобы дать возможность открывать другие экраны. Чтобы создать своё собственное окно логина для анонимного доступа, перейдите в секцию Screens в Studio и кликните Create login window.
Новый REST API
Первую версию универсального REST API, давно включенную в платформу, нельзя назвать по-настоящему RESTful – на самом деле, это просто web API, обеспечивающий CRUD и выполнение запросов через HTTP. В релизе 6.3 платформы мы представляем абсолютно новый REST API v2, следующий архитектурному стилю REST: использование URI и HTTP-методов, OAuth2 аутентификация. Вкупе с улучшенной сериализацией JSON, новый REST API существенно упрощает создание веб- и мобильных клиентских приложений.
В дополнение к CRUD-операциями над сущностями, REST API v2 позволяет выполнять заданные JPQL-запросы и вызывать методы сервисов. Методы должны быть заранее разрешены разработчиком и могут принимать и возвращать простые типы, сущности и объекты POJO, а также коллекции этих типов. Такой гибкий способ работы с сервисами избавляет вас от необходимости создавать Spring MVC контроллеры только для того, чтобы конвертировать Java-типы в JSON, - эта конвертация в большинстве случаев может выполняться автоматически. Вы просто создаёте обычные сервисы на среднем слое и регистрируете нужные методы в rest-services.xml. Затем вы можете вызывать эти методы сервисов из клиента, передавая параметры и получая результаты в JSON.
Новый REST API также предоставляет точки входа для получения информации о текущем пользователе и его разрешениях, о модели данных приложения и машиносчитываемую документацию о самом REST API.
Screen Agent
В новой версии платформы появился механизм, позволяющий адаптировать экраны UI к различным устройствам: десктоп, планшеты, смартфоны. Вы просто создаёте разные версии разметки экрана для каждого поддерживаемого устройства и указываете для них одинаковый ID, но разные значения screen agent. В результате работающее приложение само выберет нужную версию экрана в зависимости от устройства, с которого работает пользователь.
Этот простой подход не является полностью responsive, так как экран не будет трансформироваться, к примеру, при смене ориентации экрана устройства. Поэтому если вы не против написания CSS с медиа-запросами, используйте CssLayout для создания полностью отзывчивых экранов.
Кэш запросов
Кэш - это, без сомнения, наиболее эффективный способ оптимизации работы с базами данных. Теперь, кроме Кэша Сущностей, вам доступен Кэш запросов с простым API. Настолько простым, что вам достаточно задать атрибут cacheable для источника данных, LoadContext Query или ORM Query, чтобы результаты этих запросов кэшировались и использовались при следующем запросе с такими же параметрами. Само собой, запрос автоматически удаляется из кэша, когда вы обновляете или удаляете сущности типов, использованных в запросе.
Не забудьте настроить Кэш Сущностей для сущностей, используемых в кэшировании запросов – оба кэша должны работать вместе.
Заключение
В завершение этой статьи я хотел бы отметить, что большинство изменений платформы были сделаны по предложениям реальных пользователей сообщества CUBA. Мы будем рады в дальнейшем продолжать эту практику. Добро пожаловать на наш форум, где вы можете поделится своими мыслями о том, как сделать Платформу лучше.