Skip to content

Commit

Permalink
#38
Browse files Browse the repository at this point in the history
- tokens: добавлены токены для express-приложения, промежуточных слоев и маршрутов (minor)
- preset/node: добавлены компоненты express-приложения, промежуточных слоев и маршрутов (minor)
- docs: доработки по утилитам для redux (patch)
- examples: учтены новые компоненты пресета (patch)
  • Loading branch information
krutoo committed Mar 29, 2024
1 parent 34dafb1 commit d884ac9
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 38 deletions.
10 changes: 9 additions & 1 deletion docs/docs/utils/redux.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

### Удаленные данные

Для работы с удаленными данными пакет пердоставляет набор утилит `RemoteData`.
Для работы с загружаемыми данными пакет предоставляет набор утилит `RemoteData`.

Пример использования вместе с `createAction` и `createReducer` из пакета `@reduxjs/toolkit`:

Expand Down Expand Up @@ -40,10 +40,16 @@ const reducer = createReducer(initialState, builder => {
RemoteData.applyReducers<MyData, string>(actions, builder);
});

const selectors = {
// определяем базовые селекторы (данных, статуса, кол-ва загрузок и тд)
...RemoteData.createSelectors<MyDataState, { slice: MyDataState }>(rootState => rootState.slice),
};

export const MyData = {
initialState,
actions,
reducer,
selectors,
} as const;
```

Expand Down Expand Up @@ -76,4 +82,6 @@ export const MyData = createSlice({
...RemoteData.createHandlers<MyData, string>(),
},
});

// ...использование RemoteData.createSelectors по аналогии с предыдущим примером
```
44 changes: 14 additions & 30 deletions examples/node/src/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@ import { createApplication, Resolve } from '@sima-land/isomorph/di';
import { PresetNode, HandlerProvider } from '@sima-land/isomorph/preset/node';
import { AuthorsPageApp } from '../pages/authors';
import { PostsPageApp } from '../pages/posts';
import express from 'express';
import { Handler } from 'express';

export function MainApp() {
const app = createApplication();

// используем пресет "node" с базовыми компонентами, такими как logger и тд
app.preset(PresetNode());
app.preset(
PresetNode(({ override }) => {
// переопределяем провайдеры пресета
override(TOKEN.Lib.Express.pageRoutes, providePageRoutes);
}),
);

// добавляем в приложение собственные компоненты
app.bind(TOKEN.config).toProvider(provideAppConfig);
app.bind(TOKEN.server).toProvider(provideHttpServer);
app.bind(TOKEN.Pages.posts).toProvider(HandlerProvider(PostsPageApp));
app.bind(TOKEN.Pages.authors).toProvider(HandlerProvider(AuthorsPageApp));

Expand All @@ -36,31 +40,11 @@ function provideAppConfig(resolve: Resolve): AppConfig {
};
}

function provideHttpServer(resolve: Resolve): express.Application {
const postsHandler = resolve(TOKEN.Pages.posts);
const authorsHandler = resolve(TOKEN.Pages.authors);
const healthCheckHandler = resolve(TOKEN.Lib.Express.Handlers.healthCheck);

// промежуточные слои (express) доступные из пресета PresetNode
const requestHandle = resolve(TOKEN.Lib.Express.Middleware.request);
const logging = resolve(TOKEN.Lib.Express.Middleware.log);
const metrics = resolve(TOKEN.Lib.Express.Middleware.metrics);
const tracing = resolve(TOKEN.Lib.Express.Middleware.tracing);
const errorHandle = resolve(TOKEN.Lib.Express.Middleware.error);

const app = express();

// регистрируем промежуточные слои
app.use(['/', '/users', '/posts'], [requestHandle, logging, metrics, tracing]);

// регистрируем роуты
app.get('/', postsHandler);
app.get('/posts', postsHandler);
app.get('/authors', authorsHandler);
app.get('/healthcheck', healthCheckHandler);

// регистрируем промежуточный слой обработки ошибок
app.use(['/', '/users', '/posts'], [errorHandle]);

return app;
function providePageRoutes(resolve: Resolve): Array<[string, Handler]> {
// определяем маршруты страниц
return [
['/', resolve(TOKEN.Pages.posts)],
['/posts', resolve(TOKEN.Pages.posts)],
['/authors', resolve(TOKEN.Pages.authors)],
];
}
2 changes: 1 addition & 1 deletion examples/node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { MainApp } from './app';
import { TOKEN } from './tokens';

MainApp().invoke(
[TOKEN.config, TOKEN.Lib.logger, TOKEN.server, TOKEN.Lib.Metrics.httpApp],
[TOKEN.config, TOKEN.Lib.logger, TOKEN.Lib.Express.app, TOKEN.Lib.Metrics.expressApp],
(config, logger, mainServer, metricsServer) => {
mainServer.listen(config.http.ports.main, () => {
logger.info(`Server started on port ${config.http.ports.main}`);
Expand Down
3 changes: 1 addition & 2 deletions examples/node/src/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { KnownToken } from '@sima-land/isomorph/tokens';

// чтобы токены можно было использовать как в браузере так и на сервере импорты должны содержать только типы
import type { AppConfig } from './app/types';
import type { Application, Handler } from 'express';
import type { Handler } from 'express';
import type { AuthorApi } from './entities/author';
import type { PostApi } from './entities/post';

Expand All @@ -13,7 +13,6 @@ export const TOKEN = {

// далее идут токены компонентов нашего приложения
config: createToken<AppConfig>('config'),
server: createToken<Application>('http/server'),
Pages: {
posts: createToken<Handler>('pages/posts'),
authors: createToken<Handler>('pages/authors'),
Expand Down
19 changes: 17 additions & 2 deletions src/preset/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import { provideExpressRequestMiddleware } from './providers/express-request-mid
import { provideExpressTracingMiddleware } from './providers/express-tracing-middleware';
import { provideKnownHttpApiHosts } from '../server/providers/known-http-api-hosts';
import { provideLogger } from './providers/logger';
import { provideMetricsHttpApp } from './providers/metrics-http-app';
import { provideMetricsExpressApp } from './providers/metrics-express-app';
import { provideSpanExporter } from './providers/span-exporter';
import { provideSsrBridgeServerSide } from '../server/providers/ssr-bridge-server-side';
import { provideTracer } from './providers/tracer';
import { provideTracerProvider } from './providers/tracer-provider';
import { provideTracerProviderResource } from './providers/tracer-provider-resource';
import { provideMainExpressApp } from './providers/main-express-app';

/**
* Возвращает preset с зависимостями по умолчанию для frontend-микросервисов на Node.js.
Expand All @@ -44,7 +45,7 @@ export function PresetNode(customize?: PresetTuner): Preset {
preset.set(KnownToken.Tracing.tracerProviderResource, provideTracerProviderResource);

// metrics
preset.set(KnownToken.Metrics.httpApp, provideMetricsHttpApp);
preset.set(KnownToken.Metrics.expressApp, provideMetricsExpressApp);

// fetch
preset.set(KnownToken.Http.fetch, provideFetch);
Expand All @@ -55,6 +56,20 @@ export function PresetNode(customize?: PresetTuner): Preset {
preset.set(KnownToken.Axios.middleware, () => []);

// express
preset.set(KnownToken.Express.app, provideMainExpressApp);
preset.set(KnownToken.Express.pageRoutes, () => []);
preset.set(KnownToken.Express.serviceRoutes, resolve => [
['/healthcheck', resolve(KnownToken.Express.Handlers.healthCheck)],
]);
preset.set(KnownToken.Express.middleware, resolve => [
resolve(KnownToken.Express.Middleware.request),
resolve(KnownToken.Express.Middleware.log),
resolve(KnownToken.Express.Middleware.metrics),
resolve(KnownToken.Express.Middleware.tracing),
]);
preset.set(KnownToken.Express.endMiddleware, resolve => [
resolve(KnownToken.Express.Middleware.error),
]);
preset.set(KnownToken.Express.factory, provideExpressFactory);
preset.set(KnownToken.Express.Handlers.healthCheck, healthCheck);
preset.set(KnownToken.Express.Middleware.request, provideExpressRequestMiddleware);
Expand Down
31 changes: 31 additions & 0 deletions src/preset/node/providers/main-express-app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import express from 'express';
import type { Resolve } from '../../../di';
import { KnownToken } from '../../../tokens';

/**
* Провайдер основного express-приложения.
* @param resolve Функция для получения зависимости по токену.
* @return Основное express-приложение.
*/
export function provideMainExpressApp(resolve: Resolve): express.Application {
const pageRoutes = resolve(KnownToken.Express.pageRoutes);
const serviceRoutes = resolve(KnownToken.Express.serviceRoutes);
const middleware = resolve(KnownToken.Express.middleware);
const endMiddleware = resolve(KnownToken.Express.endMiddleware);

const app = express();

// маршруты страниц
for (const [routePath, routeHandler] of pageRoutes) {
app.use(routePath, middleware);
app.get(routePath, routeHandler);
app.use(routePath, endMiddleware);
}

// служебные маршруты (к ним не применяются промежуточные слои)
for (const [routePath, routeHandler] of serviceRoutes) {
app.get(routePath, routeHandler);
}

return app;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import express from 'express';
* Провайдер express-приложения метрик.
* @return Пул известных http-хостов.
*/
export function provideMetricsHttpApp(): express.Application {
export function provideMetricsExpressApp(): express.Application {
PromClient.collectDefaultMetrics();

const app = express();
Expand Down
19 changes: 18 additions & 1 deletion src/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const KnownToken = {

/** Токены компонентов сбора метрик. */
Metrics: {
httpApp: createToken<express.Application>('metrics/http-app'),
expressApp: createToken<express.Application>('metrics/express-app'),
httpHandler: createToken<Handler>('metrics/http-handler'),
},

Expand Down Expand Up @@ -173,6 +173,23 @@ export const KnownToken = {

/** Токены компонентов для работы с библиотекой express. */
Express: {
/** Токен основного express-приложения. */
app: createToken<express.Application>('express/app'),

/** Токен списка маршрутов страниц. */
pageRoutes: createToken<Array<[string, express.Handler]>>('express/page-routes'),

/** Токен списка служебных маршрутов. */
serviceRoutes: createToken<Array<[string, express.Handler]>>('express/service-routes'),

/** Токен списка промежуточных слоев для публичных маршрутов. */
middleware:
createToken<Array<express.Handler | express.ErrorRequestHandler>>('express/middleware'),

/** Токен списка промежуточных слоев для публичных маршрутов, которые подключаются после обработчика. */
endMiddleware:
createToken<Array<express.Handler | express.ErrorRequestHandler>>('express/end-middleware'),

/** Токен фабрики express-приложений. */
factory: createToken<() => express.Application>('express/factory'),

Expand Down

0 comments on commit d884ac9

Please sign in to comment.