Particuler - это пакет расширения функционала фреймворка Moleculer.
Добавляемый функционал:
- Инъекция зависимостей.
- Декораторы TypeScript.
- Валидацию на основе декораторов.
- Возможность инъекции контекста запроса напрямую в цепочке вызовов без необходимости передачи его в качестве параметров.
- Более строгая модульность бизнес-логики.
npm i particuler
// foo.service.ts
export const FooService = {
name: "foo-service"
}
// bootstrap.ts
import type { ServiceSchema } from 'moleculer'
import { ServiceFactory } from 'particuler'
import { FooService } from './foo.service'
import { FooModule } from './foo.module'
function bootstrap(): ServiceSchema {
const fooService = new ServiceFactory()
.useService(FooService)
.useBrokerConfig({ nodeID: '' })
.useModules([
FooModule
])
.create()
return fooService
}
export default bootstrap()
// foo.module.ts
import { Module } from 'particuler'
import {
FooActionsController,
FooEventsController,
FooHooksController
} from './controllers'
@Module({
actions: [FooActionsController],
events: [FooEventsController],
hooks: [FooHooksController]
})
export class FooModule {}
// foo.action.controller.ts
import { ActionsController, Action } from 'particuler'
@ActionsController()
export class FooActionsController {
@Action()
async createFoo(ctx: Context): Promise<void> {}
}
// foo.events.controller.ts
import { EventsController, Event, Name } from 'particuler'
@EventsController()
export class FooEventsController {
@Event()
@Name(FooEvents.created)
async onFooCreated(ctx: Context): Promise<void> {}
}
// foo.hooks.controller.ts
import { HooksController, Hook } from 'particuler'
@HooksController()
export class FooHooksController {
@Hook('before', 'createFoo')
async beforeCreateFoo(ctx: Context): Promise<void> {}
@Hook('after', 'createFoo')
afterCreateFoo(ctx: Context, res: unknown): void {}
@Hook('error', '*')
onError(this: object, ctx: Context, err: unknown): void {
/**
* К сожалению в данном случае нарушена совместимость с Moleculer.
*/
assert(!(this instanceof Moleculer.Service))
assert(this instanceof FooHooksController)
}
}
// foo.action.controller.ts
import { ActionsController, Action, Post } from 'particuler'
@ActionsController()
export class FooActionsController {
@Action()
@Post('/foo')
async createFoo(ctx: Context): Promise<unknown> {}
@Action('actionAlias')
async getFoo(ctx: Context): Promise<unknown> {}
}
// foo.provider.ts
import { Injectable, InjectContext } from 'particuler'
@Injectable()
export class FooProvider {
createFoo(): void {}
}
// foo.action.controller.ts
import { ActionsController, Action, PropagateContextStorage } from 'particuler'
import { FooProvider } from './foo.provider'
@ActionsController()
export class FooActionsController {
constructor(private readonly fooProvider: FooProvider) {}
@Action()
createFoo(): void {
return this.fooProvider.createFoo()
}
}
// moleculer.config.js
const {
PropagateContextActionMiddleware,
PropagateContextEventMiddleware
} = require('particuler')
module.exports = {
middlewares: [
PropagateContextActionMiddleware,
PropagateContextEventMiddleware
],
}
// foo.provider.ts
import { Injectable, InjectContext } from 'particuler'
@Injectable()
export class FooProvider {
createFoo(): void {
const ctx = InjectContext()
}
}
// foo.action.controller.ts
import { ActionsController, Action, PropagateContextStorage } from 'particuler'
import { FooProvider } from './foo.provider'
@ActionsController()
export class FooActionsController {
constructor(private readonly fooProvider: FooProvider) {}
@Action()
@PropagateContextStorage(true)
createFoo(): void {
return this.fooProvider.createFoo()
}
}
// moleculer.config.js
const {
ValidateActionMiddleware,
ValidateEventMiddleware
} = require('particuler')
module.exports = {
middlewares: [
ValidateActionMiddleware(),
ValidateEventMiddleware()
],
}
// foo.provider.ts
import { Injectable } from 'particuler'
@Injectable()
export class FooProvider {
deleteFoo(id: number): void {}
}
// delete-foo.dto.ts
import { IsDefined } from 'class-validator'
class DeleteFooDto {
@IsDefined()
id: number
}
// foo.action.controller.ts
import { ActionsController, Action, Validate } from 'particuler'
import { DeleteFooDto } from './delete-foo.dto'
@ActionsController()
export class FooActionsController {
@Action()
deleteFoo(@Validate() params: DeleteFooDto): void {
return this.fooProvider.deleteFoo(params.id)
}
}