Перейти до основного вмісту

Адаптери

інформація

Обробка http запитів та ws здійснюється силами адаптерів ядра обчислення. Виконання обробників здійснюється в рамках життєвого циклу запиту чи події. Життєві цикли включають в собі валідацію маршруту, залучення типів приватизації маршрутів, логування, формування контексту і т.д.

примітка

Адаптери реалізовують абстрактний, загальний інтерфейс, що надає можливість створювати інші кінцеві адаптери, які в подальшому можуть бути призначені завдяки конфігураційному налаштування ядра обчислень.

Архітектура

При ініціалізації ядра обчислень відбувається послідовний запуск зʼєднувачів, першим із яких є зʼєднувач обчислень, що автоматично активує послідовний запуск сервісів. У цьому порядку також включений сервіс комбінацій CombinationService, призначений для послідовного запуску фабрик.

Оскільки існує декілька реалізацій адаптерів конкретного протоколу, кожен з них успадковує абстрактний адаптер відповідного протоколу, що визначає правила реалізації адаптерів. Фабрика адаптерів, на основі конфігураційних даних, визначає, яку саме реалізацію адаптера протоколу запустити, після чого здійснюється запуск відповідного адаптера.

adapter-arch.svg

інформація

Запуск сервісу комбінацій, а відповідно і запуск адаптерів, можливий лише після обробки конфігураційних файлів, активації можливостей логування, завантаження структури бізнес-схеми в пам'ять ядра обчислень та запуску сервісу контекстів. Ця послідовність зумовлена залежністю обробки запитів від вище описаних сервісів.

примітка

Запуск адаптера включає в себе активацію веб-сервера за конкретним протоколом, на певному хості та порту, із можливістю використання ssl сертифікатів та закритих ключів.

Застосування

Використання адаптерів відрізняється відповідно до протоколу: http адаптер взаємодіє з заголовками, методами http та статусними кодами, тоді як адаптер ws працює згідно з довільним контрактом, який спеціально формується самостійно застосунком X-Fiber.

http адаптер

Адаптер координує http взаємодію ядра обчислень із попередньо завантаженою бізнес-схемою та іншими джерелами взаємодії, що можуть включати веб-клієнти, нативні застосунки, інші веб-сервери та інші суб'єкти.

http адаптер оперує власним життєвим циклом обробки запитів, що включає в себе CORS (Cross-Origin Resource Sharing), загальну валідацію вхідних даних, пошук та визначення деталей кінцевого маршруту, а також їх обробку. Він здійснює валідацію даних запиту відповідно до опису деталей кінцевого маршруту, формує контекст запиту та передає його до обробника маршруту разом з іншою необхідною інформацією. Після обробки запиту формує результат і повертає його як відповідь на запит.

warning

Ми вдосконалюємо наші практики, такі як використання Rate Limiter для обмеження частоти http запитів, з метою зменшення ризиків, пов'язаних з можливими DDoS атаками та іншими загрозами. У майбутніх версіях ми плануємо впровадити rate-limiter-flexible.

ws адаптер

Адаптер координує ws взаємодію ядра обчислень із попередньо завантаженою бізнес-схемою та іншими джерелами взаємодії, що можуть включати веб-клієнти, нативні застосунки тощо.

Адаптер взаємодіє в межах власного життєвого циклу обробки запитів, що включає в собі загальну валідацію даних, пошук та визначення деталей кінцевої події, а також її обробку. Він проводить валідацію даних запиту відповідно до опису деталей події, формує контекст події та передає його до обробника події разом з іншою необхідною інформацією.

інформація

Оскільки протокол ws не визначає конкретну структуру побудови подій, X-Fiber впроваджує власний формат взаємодії. Цей формат включає в себе тип події, що аналогічний http методу, оскільки комунікаційні варіанти обмежені (події від сесії до сесії, від сесії до кімнати, від сесії до сервісу тощо), статус події - спрощений варіант коду статусу, версія події, динамічні параметри та тіло події, тип приватизації та відповідне поле токену. Цей перелік вважається достатнім для структуризації. Також включається назва події, що є аналогом кінцевого маршруту.

Побудова подій та опис обробників детально описана в розділі "Бізнес-схема".

порада

Рекомендуємо утриматися від використання мобільних веб-застосунків через протокол ws, оскільки дії користувача, такі як вимкнення екрану чи недостатня якість інтернет-з'єднання, можуть прямо впливати на стабільність з'єднання та, відповідно, на користувацький досвід. Ми рекомендуємо використовувати альтернативи, такі як повідомлення push, які можуть забезпечити більш якісний користувацький досвід.

Застосування

Для обробки запитів http адаптер має уніфікований маршрут, димамамічними параметрами в який описується кінцевий маршрут. Адаптер аналізуючи динамічні параметри знаходить опис деталей маршруту та сам обробник маршруту, проводячи життєвий цикл цього запиту.

import { injectable, inject } from '~packages'
import { CoreSymbols } from '~symbols'
import { StatusCode } from '~common'
import { AbstractHttpAdapter } from './abstract.http.adapter'

import type {
IAbstractHttpAdapter,
NAbstractHttpAdapter,
IDiscoveryService,
ILoggerService,
IContextService,
NContextService
} from '~types'


@injectable()
export class FastifyHttpAdapter extends AbstractHttpAdapter<"fastify"> implements IAbstractHttpAdapter {
protected readonly _ADAPTER_NAME = FastifyHttpAdapter.name;
protected _instance: NAbstractHttpAdapter.Instance<"fastify"> | undefined;
// ... other properties

constructor(
@inject(CoreSymbols.DiscoveryService)
protected readonly _discoveryService: IDiscoveryService,
@inject(CoreSymbols.LoggerService)
protected readonly _loggerService: ILoggerService,
@inject(CoreSymbols.ContextService)
protected readonly _contextService: IContextService,
// ... other inject structures
) {
super();
}

public async start(): Promise<void> {
this._instance = fastify({
// ... fastify options
});
this._instance.all(this._config.urls.api + "*", this._apiHandler);

// ... other method logic
}

protected _apiHandler = async (
req: NAbstractHttpAdapter.Request<"fastify">,
res: NAbstractHttpAdapter.Response<"fastify">
): Promise<void> => {

const service = this._schemas.get(route.service);
if (!service) {
// ... send response
}

const domain = service.get(route.domain);
if (!domain) {
// ... send response
}

if (!route.routes) {
// ... send response
}

const act = schemaResult.action + "{{" + req.method.toUpperCase() + "}}";
const action = domain.routes.get(act);
if (!action) {
// ... send response
}

// 1. parse dinamyc params and check required params
// 2. parse query params and check requered params
// 3. parse headers and check required headers
// 4. resolve supported language

const store: NContextService.Store = {
// ... store structure
};

try {
await this._contextService.storage.run(store, async () => {
const context: NAbstractHttpAdapter.Context = {
store: store,
user: {},
system: {},
};

switch (action.scope) {
case "public:route":
break;
case "private:user":
// try add user session to context
break;
case "private:system":
// try add system session to context
break;
}

const result = await action.handler(
// ... add handler args
);

if (!result) {
return res.status(StatusCode.NO_CONTENT).send();
}

// resolve result and processing response
});
} catch (e) {
// resolve catch error and processing responce
} finally {
this._contextService.exit();
}
};
}
примітка

Адаптер виконує обробку кінцевого маршруту у блоках try / catch, через який він керує винятками та визначає їх тип для подальшої формування відповіді на запит. У випадку виникнення помилки, він визначає тип помилки та генерує відповідну відповідь, а також реєструє цей випадок, використовуючи механізми логування або висилання сповіщень через alert адміністратору системи тощо.