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>
important

В элементе <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"/>
important

Поля будут заполнены из параметров 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 varchar(255),
class varchar(255),
context bytea
  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.