1.0.1 • Published 8 months ago

particuler v1.0.1

Weekly downloads
-
License
SEE LICENCE IN LI...
Repository
github
Last release
8 months ago

Particuler

Описание

Particuler - это пакет расширения функционала фреймворка MoleculerJS.

Пакет добавляет следующий функционал:

  • Инъекция зависимостей.
  • Декораторы TypeScript.
  • Валидацию на основе декораторов.
  • Возможнсоть инъекции контекста запроса напрямую в цеопчке вызовов без необходимости передачи его в качестве параметров.
  • Более строгая модульность бизнес-логики.

Философия

MoleculerJS предоставляет богатый функционал из коробки. Но архитектура построения сервиса, предлагаемая командой фреймворка, не подразумевает создания комплексых проектов, находящихся на долгой поддержке у большой команды разработчиков. Каждый микросервис написанный на MoleculerJS отличается от любого другого микросервиса написанного на этом же фреймворке. Очень часто различие настолько кардинальное, что разработчики сталкиваются с трудностями при переходе на другие проекты даже в рамках одной компании. Отсутствие строгой архитектуры, протекание абстракций (сontext с информацией о фреймворке, который передается в качестве аргументов во все функции по цепочке), использование императивно-декларативного стиля написания сервиса, что неибежно приводит к появлению других стилей программирования в кодовой базе проекта и пр., все это призван решить данный пакет.

Каждый бизнес-процесс должен представлять из себя атомарный модуль со строго связным функционалом. Каждый модуль может быть примиксован к одному из сервисов проекта. Взаимодействие между модулями возможно только через публичные провайдеры или события благодаря чему все зацепления между модулями будут легко прослеживаемыми. Контекст запроса может быть использован только в провайдерах общего функционала, которые могут быть инжектированы в любой модуль через инъекцию зависимостей в конструкторе класса.

Установка

Npm

npm i particuler
npm -D @types/particuler

Yarn

yarn add particuler
yarn add -D @types/particuler

Декораторы Action

// foo.action.controller.ts
import { ActionsController } from 'particuler/common';

@ActionsController()
export class FooActionsController {
  constructor(private readonly fooProvider: FooProvider) {}

  @Action()
  @Get('/foo')
  @RequiredPermission('/foo-service/foo')
  @Description('Some action description')
  @Summary('Action summary test')
  async getFoo(ctx: Context): Promise<unknown> {
    return this.fooProvider.getFoo(ctx.params);
  }

  @Action('actionAlias')
  async getAllFoo(ctx: Context): Promise<unknown> {}
}

Контроллеры

// foo.action.controller.ts
import { ActionsController } from 'particuler/common';

@ActionsController()
export class FooActionsController {
  constructor(private readonly fooProvider: FooProvider) {}

  @Action()
  async getFoo(ctx: Context): Promise<unknown> {
    return this.fooProvider.getFoo(ctx.params);
  }
}


// foo.events.controller.ts
import { EventsController } from 'particuler/common';

@EventsController()
export class FooEventsController {
  constructor(private readonly fooEventProvider: FooEventProvider) {}

  @Event()
  @Name(FooEvents.created)
  async fooCreated(ctx: Context): Promise<void> {
    return this.fooEventProvider.onFooCreated(ctx.params);
  }
}


// foo.hooks.controller.ts
import { HooksController } from 'particuler/common';

@HooksController()
export class FooHooksController {
  constructor(private readonly fooProvider: FooProvider) {}

  @Hook('before', 'getFoo')
  async beforeGetFoo(ctx: Context): Promise<void> {
    return this.fooProvider.check(ctx.params);
  }

  @Hook('after', 'getFoo')
  afterFoo(ctx: Context, res: unknown): void {}

  @Hook('error', '*')
  onError(this: object, ctx: Context, err: unknown): void {
    assert(!(this instanceof Moleculer.Service));
    assert(this instanceof FooHooksController);
  }
}


// foo.module.ts
import {
  FooActionsController,
  FooEventsController,
  FooHooksController,
} from './controllers';

@Module({
  actions: [FooActionsController],
  events: [FooEventsController],
  hooks: [FooHooksController],
})
export class FooModule {}
// bootstrap.ts
import type { ServiceSchema } from 'moleculer';
import { ServiceFactory } from 'particuler/core';

function bootstrap(): ServiceSchema {
  const myAwesomeService = new ServiceFactory()
    .useService(MyAwesomeMoleculerService)
    .useBrokerConfig({ nodeID: '' })
    .useModules([
      FooModule,
    ])
    .create();

  return myAwesomeService;
}

export default bootstrap();

Валидация параметров

// moleculer.config.ts
import {
  ValidateActionMiddleware,
  ValidateEventMiddleware
 } from 'particuler/common';

export = {
  middlewares: [
    ValidateActionMiddleware(),
    ValidateEventMiddleware(),
  ]
}


// foo.action.controller.ts
import { ActionsController } from 'particuler/common';

@ActionsController()
export class FooActionsController {
  @Action()
  async getFoo(@Validate() params: RequestDto): Promise<void> {}
}

Инъекция контекста

// moleculer.config.ts
import {
  PropagateContextActionMiddleware,
  PropagateContextEventMiddleware
 } from 'particuler/common';

export = {
  middlewares: [
    PropagateContextActionMiddleware,
    PropagateContextEventMiddleware,
  ]
}


// foo.action.controller.ts
import { ActionsController } from 'particuler/common';

@ActionsController()
export class FooActionsController {
  constructor(private readonly fooProvider: FooProvider) {}

  @PropagateContextStorage(true)
  async getFoo(ctx: Context): Promise<unknown> {
    return this.fooProvider.getFoo();
  }
}


// foo.provider.ts
@Injectable()
export class FooProvider {
  getFoo(): unknown {
    const ctx = InjectContext();
  }
}
1.0.1

8 months ago

1.0.0

8 months ago

0.0.0-rc.9

8 months ago

0.0.0-rc.8

8 months ago

0.0.0-rc.7

8 months ago

0.0.0-rc.6

8 months ago

0.0.0-rc.0

10 months ago

0.0.0-rc.1

11 months ago

0.0.0

11 months ago