Маршрутизатор
Документ "Маршрутизатор" відповідає за роботу з http
запитами. Він визначає шляхи (маршрути) для обробки різних типів запитів і відповідних їм дій. Кожен маршрут описується в форматі
REST API
, що дозволяє чітко визначити структуру та тип запиту, а також обробник (контролер), який буде виконувати логіку
для цього маршруту. Такий підхід дозволяє забезпечити структурованість та чіткість управління HTTP-запитами
в системі та
дозволяє реалізувати принципи RESTful
архітектури.
Архітектура
При необхідності опису маршрутів в предметній області необхідно створити документ "Маршрутизатор" з переліком необхідних маршрутів.
Документ "Маршрутизатор" повинен бути зареєстрований в документі "Реєстр" предметної області, який в свою чергу, має бути зареєстрований в відповідному сервісі, включеному до бізнес-схеми. Це гарантує, що при запуску ядра обчислень будуть завантажені всі маршрути маршрутизатора. При виклику та виконанні конкретного обробника запиту ядро обчислень надасть актуальний знімок структури бізнес-схеми, де вже наявний опис кінцевого маршруту разом з його обробником.
Структура URL
Загальна маска url:
Метод: HTTP метод.
Шлях: {protocol}://${host}:${port}/{baseUrl}/:{service}/:${domain}/:${version}/:${endpoint}/:${dynamic-parameter-n}?{query-parameter-n}
Заголовки: Обʼєкт з п ереліком заголовків.
де:
protocol
- тип протоколу (обовʼязково).host
- назва хосту (обовʼязково).port
- номер порту (обовʼязково).baseUrl
- базовий маршрут, який описується в конфігурації сервера. За замовчуванням/v1/call/api/
(обовʼязково).service
- назва сервісу (обовʼязково).domain
- предметна область (обовʼязково).version
- версія кінцевого маршруту (обовʼязково).endpoint
- назва кінцевого маршруту (обовʼязково).dynamic-parameter-n
- динамічні параметри (опціонально).query-parameter-n
- query параметри (опціонально).
- Приклад запиту користувача по його унікальному іденти фікатору:
GET
http://0.0.0.0:11001/v1/call/api/BusinessAdmin/BusUsers/v1/get-one/f47ac10b-58cc-4372-a567-0e02b2c3d479
- Приклад запиту користувачів з сортуванням по даті створення записів та з лімітом в 5 записів.
Метод: GET
http://0.0.0.0:11001/v1/call/api/BusinessAdmin/BusUsers/v1/find-many?order=desc&limit=5
Склад
Маршрутизатор поєднує в собі дві функції - безпосередньо саму маршрутизацію, яка описується за правилами REST API
та
створення обробників кінцевих маршрутів http
запитів.
Загальна структура маршрутизатора
type HttpMethod =
| "GET"
| "POST"
| "PUT"
| "PATCH"
| "DELETE"
| "OPTIONS"
| "HEAD"
| "TRACE";
type AuthScope = 'public:route' | 'private:user' | 'private:system'
type Version = "v1" | "v2" | "v3" | "v4" | "v5" | string;
type RouteParams = {
name: string;
scope: "required" | "optional";
};
type HeaderParams = {
name: string;
scope: "required" | "optional";
};
type QueryParameter =
| "string"
| "string[]"
| "number"
| "number[]"
| "boolean"
| "boolean[]";
type QueryParams = {
name: string;
format: QueryParameter[];
scope: "required" | "optional";
};
type ApiHandler = (
...args // arguments
) => Promise<Response | void> // response structure
export type RouterStructure<R extends string = string> = {
[key in R]: {
[method in HttpMethod]?: {
scope?: AuthScope;
version?: Version;
params?: RouteParams[];
headers?: HeaderParams[];
queries?: QueryParams[];
handler: ApiHandler;
};
};
};
де:
- Типи:
HttpMethod
- перелік можливихhttp
методів.AuthScope
- перелік типів приватизації.Version
- тип версії.RouteParams
- тип динамічного параметра кінцевого маршруту.HeaderParams
- тип заголовка кінцевого маршруту.QueryParameter
- тип query параметра кінцевого маршруту.ApiHandler
- структура обробника запиту.RouterStructure
- структура документа "Маршрутизатор".
- Структури обʼєкта маршруту:
key
- строкове представлення назви кінцевого маршруту.method
-http
метод кінцевого маршруту.scope
- тип приватизації кінцевого маршруту.version
- версія кінцевого маршруту.params
- динамічні параметри, які передаються вurl
.headers
- заголовки, які передаються разом з запитом.queries
- query параметри, які передаються вurl
.handler
- обробн ик запиту.
X-Fiber
перевіряє назви кінцевих маршрутів, які не повинні мати слеш або крапку, а при потребі створення назви
кінцевого маршруту використовуйте slug або на худий кінець - camelCase
.
В разі наявності в кінцевому маршруті слешу або крапки ядро обчислень при завантаженні схеми видасть помилку з вказанням
на місце розташування кінцевого маршруту в бізнес-схемі.
Опис кінцевого маршруту складається з опису динамічних параметрів маршруту, query параметрів, заголовків, типу приватизації
та версії маршруту. X-Fiber
надає можливість валідації деталей маршрутизації, завдяки яким на етапі отримання запиту,
адаптер http
протоколу ядра обчислень проведене необхідні перевірки.
Деталі маршруту
Деталі маршруту складаються з:
- Версії кінцевого маршруту (за замовчуванням
v1
), - Типу приватизації (за замовчуванням
public:route
), - Динамічних параметрів (за замовчуванням пустий масив),
- Query параметрів (за замовчування пустий масив),
- Заголовки (за замовчуванням пустий масив).
Версія
Версія кінцевого маршруту дозволяє відокремити минулі реалізації кінцевих маршрутів з якими працюють відповідні джерела взаємодії від нової, що спрощує підтримку API без потреби створювати кінцеві маршрути аналогічного призначення з словами синонімами.
За замовчуванням кінцевому маршруту присвоюється версія v1
. Окремо варто підкреслити, що версії потрібно вказувати v1 / v2 / v3 / v4 і т.д.
Тип приватизації
Тип приватизації визначає, чи потребує маршрут автентифікації та даних сесії, яка вже зберігається на сервері. З розрахунку типу приватизації випливає можлива структура контексту виконання запиту. Так, для приватних кінцевих маршрутів контекст буде містити ще й дані про сесію.
X-Fiber
підтримує наступні типи приватизації:
export type AuthScope = "public:route" | "private:user" | "private:system";
де:
public:route
: Цей тип приватизації використовується для публічних маршрутів, які доступні для всіх користувачів без обмежень.private:user
: Цей тип приватизації застосовується до запитів, що відносяться до конкретного користувача. Для цього типу потрібні відповідні токени доступу користувача для аутентифікації та авторизації, які повинні надходити в заголовках запиту.private:system
: Цей тип приватизації використовується для системних запитів, які взаємодіють зі службами або компонентами системи. Для цього типу також потрібні відповідні системні токени доступу, які повинні надходити в заголовках запиту.
Залежно від типу приватизації, http
адаптер ядра обчислень формує відповідний контекст виконання, що враховує наявність
відповідних токенів доступу, окрім випадку з public:route
. Деталі структури контексту виконання обробника запиту
описані в "Обробник запиту"
Динамічні параметри
Динамічні параметри використовуються при необхідно надання інформації за унікальними класифікаторами сутностей - ідентифікатор, імен тощо.
import { setRouter, ApiRequest, Context, Agents, ApiResponse } from 'x-fiber/proton'
type GetOnePrams = {
userId: 'required'
partnerId: 'optional'
}
export const BusUsersAggRouter = setRouter<'getOne'>({
getOne: {
GET: {
params: [
{
name: 'userId',
scope: 'required',
},
{
name: 'partnerId',
scope: 'optional',
},
],
handler: async (
request: ApiRequest<void, GetOnePrams>,
agents: Agents,
context: Context
): Promise<ApiResponse> => {
// ... route business logic
},
},
},
});
де:
params
- обʼєкт опису динамічних параметрів.name
- назва параметра, якому буде присвоєне значення вrequest.params
.scope
- обовʼязковість параметра. Якщоscope
=required
, то адаптер протоколу поверне помилку про відсутність такого параметра в структурі маршруту запиту. Якщоoptional
, в разі відсутності буде присвоєно вrequest.params
значенняnull
до відповідної назви заголовку.
В разі виявлення помилки валідації адаптер http
протоколу поверне наступну помилку:
{
"type": "fail",
"code": "0002.0001.0005",
"message": "Dynamic parameter '{dynamic-param-name}' is required."
}
Перелік обʼєктів грає важливу роль! Послідовність аргументів визначає який аргумент з url
буде присвоєний якому
значенню.
Опис динамічних та сталих параметрів X-Fiber
сприймає як динамічні, тому в разі потреби опису сталого параметру -
включайте його в загальний опис в необхідній послідовності
Query параметри
Query параметри використовуються для опису умов виконання запиту. Такими умовами можуть бути - фільтрація, пагінація,
визначення лімітів на кількість записів тощо. X-Fiber
надає можливість не тільки здійснює валідацію query параметрів,
а й перетворює значення в описаний тип.
import { setRouter, ApiRequest, Context, Agents, ApiResponse } from 'x-fiber/proton'
type GetOneQueries = {
limit: 'required'
sort: 'optional',
}
export const BusUsersAggRouter = setRouter<'getOne'>({
getOne: {
GET: {
queries: [
{
name: 'limit',
format: 'number',
scope: 'required',
},
{
name: 'sort',
format: 'string',
scope: 'optional',
},
],
handler: async (
request: ApiRequest<void, void, GetOneQueries>,
agents: Agents,
context: Context
): Promise<ApiResponse> => {
// ... route business logic
},
},
},
});