Skip to main content

Маршрутизация

С помощью маршрутизации можно контролировать формирование URL адресов страниц N2O.

Страницы в N2O открываются по следующему URL:

http://localhost:8080/#/[route]

, где route адрес N2O страницы.

Адреса страниц имеют иерархическую структуру. Если страница вложенная (открыта через open-page), то её адрес будет содержать адрес предыдущей страницы и добавочную часть.

Эта добавочная часть называется маршрутом и задаётся атрибутом route. Маршрут должен начинаться со знака "/", например, route="/home".

Маршрут может содержать параметры пути, которые задаются через двоеточие, например, /:master_id/detail. Параметр пути указывает на значение в источниках данных.

note

Т.к. адреса N2O страниц формируются иерархически, то параметры пути будут сохраняться в адресах всех вложенных страниц. Следовательно, все параметры пути должны быть уникальными.

Маршрутизация в меню навигации

Начальные адреса страниц задаются в меню навигации приложения:

Маршрут страниц в меню навигации
<application>
<header>
<nav>
<menu-item name="Главная">
<!-- Страница откроется по адресу
http://localhost:8080/#/home -->
<open-page page-id="home" route="/home"/>
</menu-item>
</nav>
</header>
</application>
note

Если route не задан, адресом по умолчанию будет id страницы.

Можно указать пустой маршрут route="/", в таком случае страница будет открываться по корневому адресу.

Корневой адрес регистрируется автоматически, если в структуре приложения задать атрибут welcome-page-id:

Начальная страница приложения
<application welcome-page-id="homePage">
...
</application>
note

Если в качестве welcome-page-id используется не index.page.xml, то в application.properties нужно добавить настройку с указанием домашней страницы n2o.homepage.id=homePage.

Маршрутизация в боковых панелях

Некоторые боковые панели могут появляться на определенных адресах приложения. Эта возможность задается атрибутом path.

Адреса боковых панелей
<sidebars>
<sidebar path="/home" title="Главная"/>
<sidebar path="/search" title="Поиск"/>
<sidebar path="/profile/*" title="Профиль"/>
<sidebar path="/store/**" title="Карточка магазина"/>
<sidebar path="/client/:person_id/**" title="Карточка клиента"/>
</sidebars>

Одна звездочка * определяет любой адрес до первого разделителя /. Двойная звездочка ** определяет любые последующие адреса.

Параметры пути боковой панели

В адресе боковой панели можно задавать параметры пути через двоеточие.

Параметр в пути боковой панели
<sidebar path="/client/:person_id/**" title="Карточка клиента">
...
</sidebar>

Параметры пути можно использовать в меню навигации боковой панели.

Использование параметра в пути боковой панели
<sidebar path="/client/:person_id/**" title="Карточка клиента">
<nav>
<menu-item name="Документы">
<open-page page-id="docs" route="/client/:person_id/docs">
<params>
<path-param name="person_id" value=":person_id"/>
</params>
</open-page>
</menu-item>
</nav>
</sidebar>

Значение параметра пути боковой панели задается в атрибуте value через ведущее двоеточие value=":person_id".

Маршрутизация вложенных страниц

Маршрут вложенных страниц задается атрибутом route в действии, вызывающем открытие страницы:

Маршрут дочерней страницы
<button label="Дочерняя страница">
<!-- Если маршрут текущей страницы `/parent`,
то дочерняя страница будет открыта по адресу
http://localhost:8080/#/parent/child -->
<open-page page-id="childPage"
route="/child"/>
</button>

Если route не задан, маршрутом по умолчанию будет идентификатор действия (или кнопки).

Параметры пути страницы

В маршруте вложенной страницы можно задавать параметры пути через двоеточие, а значения параметров через элемент <path-param>:

Маршрут дочерней страницы с параметром пути
<open-page page-id="docs"
route="/:person_id/docs">
<params>
<!-- Если маршрут текущей страницы равен /persons,
а поле id в источнике данных persons модели resolve равно 123,
то дочерняя страница будет открыта по адресу
http://localhost:8080/#/persons/123/docs
-->
<path-param name="person_id"
value="{id}"
datasource="persons"
model="resolve"/>
</params>
</open-page>

Параметры запроса страницы

Помимо параметров пути, адреса страниц могут иметь параметры запроса. Они задаются в URL как "ключ=значение" после знака "?":

http://localhost:8080/#/[route]?param1=[value1]&param2=[value2]

Имя параметра запроса должно быть уникально в рамках одной страницы. Параметры запроса задаются через элемент query-param:

Маршрут дочерней страницы с параметром запроса
<open-page page-id="docs"
route="/docs">
<params>
<!-- Если маршрут текущей страницы равен /persons,
а поле id в источнике данных persons модели resolve равно 123,
то дочерняя страница будет открыта по адресу
http://localhost:8080/#/persons/docs?person_id=123
-->
<query-param name="person_id"
value="{id}"
datasource="persons"
model="resolve"/>
</params>
</open-page>

Использование параметров страницы

Параметры, переданные при открытии страницы, можно использовать в фильтрах и значениях полей.

Можно передать параметр и использовать его в одном и том же действии:

Передача и использование параметра страницы
<open-page page-id="docs"
route="/:person_id/docs">
<params>
<!-- На страницу docs передается параметр person_id
со значением id на текущей странице -->
<path-param name="person_id" value="{id}"/>
</params>
<datasources>
<datasource id="docs" query-id="docs">
<filters>
<!-- На странице docs в источнике данных docs фильтруется поле person.id
по значению переданному в параметре person_id -->
<eq field-id="person.id" param="person_id"/>
</filters>
</datasource>
</datasources>
</open-page>

Маршрутизация выборки

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

GET http://localhost:8080/n2o/data/[route]

, где route маршрут выборки.

Адрес выборки содержит адрес текущей страницы и добавочную часть. Добавочная часть выборки называется маршрутом и задается атрибутом route:

Маршрут выборки
<datasources>
<datasource id="persons"
query-id="persons"
route="/list">
<!-- Если адрес текущей страницы /persons,
то данные выборки будут загружаться по адресу
http://localhost:8080/n2o/data/persons/list -->
</datasource>
</datasources>

Фильтрам выборки можно задать имя параметра запроса через атрибут param:

Параметры запроса фильтра выборки
<datasource id="persons"
query-id="persons"
route="/list">
<filters>
<!-- Фильтрация по name будет задаваться по адресу
http://localhost:8080/n2o/data/persons/list?name_like=Joe -->
<like filter-id="name"
param="name_like"/>
</filters>
</datasource>

Маршрутизация операций

Данные операций N2O загружаются по следующему URL адресу:

POST/PUT/DELETE http://localhost:8080/n2o/data/[route]

, где route маршрут операций.

Адрес операции содержит адрес текущей страницы и добавочную часть. Добавочная часть операции называется маршрутом и задается атрибутом route:

Маршрут операции
<button label="Сохранить">

<!-- Если текущая страница /persons,
то операция будет выполнена по адресу
POST http://localhost:8080/n2o/data/persons -->
<invoke operation-id="create"
route="/new"
method="POST"/>
</button>

Параметры пути операции

Можно задать параметры пути операции через элемент <path-param>:

Маршрут операции с параметром пути
<button label="Сохранить">

<!-- Если текущая страница /persons,
а значение параметра id в источнике persons модели resolve равно 123,
то операция будет выполнена по адресу
PUT http://localhost:8080/n2o/data/123/persons -->
<invoke operation-id="update"
route="/:person_id/update"
method="PUT">
<path-param name="person_id"
value="{id}"
datasource="persons"
model="resolve"/>
</invoke>
</button>

Параметры тела запроса

Телом запроса операции по умолчанию является текущая модель источника данных. Можно задать дополнительные значения в теле запроса через элементы <form-param>:

Маршрут операции с параметром тела запроса
<button label="Сохранить">
<!-- Отправка всех данных источника main и
дополнительно значение doc.number и doc.serial
из источника docs модели resolve
-->
<invoke operation-id="update"
datasource="main"
route="/update"
submit-all="true">
<form-param id="doc.number"
value="{number}"
datasource="docs"
model="resolve"/>
<form-param id="doc.serial"
value="{serial}"
datasource="docs"
model="resolve"/>
</invoke>
</button>
info

В элементе <form-param> задается идентификатор id поля, а не имя параметра name как в случае с параметрами пути. Т.к. параметры тела запроса устанавливаются в теле запроса в json формате, а не в его URL или заголовках.

note

Все данные основного источника данных можно не отправлять установив submit-all="false". В таком случае в теле запроса будут отправлены только дополнительные значения, заданные через <form-param>.

Использование параметров операции

Параметры операции можно использовать в полях операции объекта с помощью атрибута param:

Использование параметров операции
<object>
<operations>
<operation>
<invocation>...</invocation>
<in>
<!-- Значение поля person.id возьмется из
значения параметра пути person_id
заданного в URL адреса операции
http://localhost:8080/n2o/data/123/persons -->
<field id="person.id" param="person_id"/> <!-- person_id=123 -->
<!-- Значения полей doc.number и doc.serial
возьмутся из тела запроса,
т.к. были переданы через <form-param> -->
<field id="doc.number"/>
<field id="doc.serial"/>
</in>
</operation>
</operations>
</object>

Задание значений полей через параметры

Через параметры в URL адреса страницы можно задавать значения полей. Для этого необходимо использовать атрибут param:

Значение простого поля, заданное через параметр
<!-- Если адрес текущей страницы /card, то
значение поля name можно задать по адресу
http://localhost:8080/#/card?name=Joe -->
<input-text id="name" param="name"/>
info

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

Задание значений списковых полей через параметры

Списковые поля можно задавать через параметры param, используя только поле id:

Значение спискового поля, заданное через параметр
<!-- Если адрес текущей страницы /card, то
значение поля gender можно задать по адресу
http://localhost:8080/#/card?gender_id=1 -->
<select id="gender"
param="gender_id">
<options>
<option id="1" name="Мужской"/> <!-- ?gender_id=1 -->
<option id="2" name="Женский"/> <!-- ?gender_id=2 -->
</options>
</select>

Задание значений интервальных полей через параметры

Интервальные поля можно задавать через параметры в атрибутах begin-param и end-param:

Значение интервального поля, заданное через параметр
<!-- Если адрес текущей страницы /card, то
значение поля period можно задать по адресу
http://localhost:8080/#/card?begin=2021-01-01&end=2021-12-31 -->
<date-interval id="period"
begin-param="begin"
end-param="end"/>

Репликация маршрутизации

Адреса маршрутов страниц, выборок и операций регистрируются по мере работы приложения и сохраняются в памяти N2O сервера. При горизонтальном масштабировании серверов необходимо реплицировать эту информацию, иначе при переадресации запросов на новый сервер некоторые адреса не будут открываться с ошибкой 404.

Существует два способа репликации:

  • Через jdbc
  • Через Redis

Репликации роутов через jdbc

  1. Задайте настройку n2o.config.register.store-type=jdbc.
  2. Настройте JdbcTemplate.
  3. Для изменения названия используемой таблицы необходимо задать настройку n2o.config.register.jdbc.table-name=route_repository.

Структура таблицы:

id uuid PRIMARY KEY,
url char(255),
class char(255),
context binary
  1. Для автоматического создания таблицы при старте сервиса необходимо задать настройку n2o.config.register.jdbc.create-table=true.

Репликации роутов через Redis

  1. Задайте настройку n2o.config.register.store-type=redis.
  2. Настройте ConnectionFactory для Jedis или Lettuce:
Jedis
@Bean
JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
...
return connectionFactory;
}
Lettuce
@Bean
LettuceConnectionFactory redisConnectionFactory() {
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory();
...
return connectionFactory;
}
  1. Настройте RedisTemplate
@Bean
public RedisTemplate redisTemplate() {
RedisTemplate template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory());
...
return template;
}
  1. Для изменения ключа, по которому будут сохраняться пути, необходимо задать настройку n2o.config.register.redis.key=routes.