3.6.1 • Published 8 days ago

@qq-framework/ddd v3.6.1

Weekly downloads
-
License
ISC
Repository
-
Last release
8 days ago

ddd

Como disparar eventos com nestjs

  • Dependencias

    • "@qq-framework/ddd": "^3.1.1"
    • @qq-framework/basic": "^3.0.0"
  • Crie um provider em seu módulo utilizando a classe DomainEventPublisherNestImplService do @qq-framework/ddd

// any.module.ts

import { EventPublisher } from '@nestjs/cqrs'
import { DomainEventPublisherNestImplService } from '@qq-framework/ddd'

@Module({
    controllers: [
    ...    
    ],
    providers: [
        ...
        {
            provide: 'NestDomainEventPublisher',
            useFactory(eventPublisher: EventPublisher) {
                return new DomainEventPublisherNestImplService(eventPublisher)
            },
            inject: [EventPublisher],
        }
        ...
    ],
    imports: [
        ...
    ],
})
export class CoreModule implements NestModule {}
  • Injete o provider criado no construtor da classe de serviço onde deseja disparar o evento, utilizando a interface DomainEventPublisherService do @qq-framework/basic
//any.service 

import {
    AggregateRoot,
    DomainEventPublisherService,
} from '@qq-framework/basic'

...

constructor(
        @Inject('NestDomainEventPublisher') private readonly publisher: DomainEventPublisherService<AggregateRoot>
    ) {    
    }

...
  • Para publicar o evento, utilize o publisher injetado na sua classe, passando o seu agregado.
...

const publish = await this.publisher.publish(campoExistente.value)
if (publish.isFailure()) return R.failure(publish.error)

...

Migrando para versão 2.x.x

Se você estiver realizando uma migração da versão 1.x.x para versão 2.x.x os seguintes scripts devem ser executados no banco de dados da sua aplicação:

alter table public.process_log add column error_class varchar null;
alter table public.process_log add column error_type varchar null;

alter table public.single_thread_command_log add column error_class varchar null;
alter table public.single_thread_command_log add column error_type varchar null;

alter table public.event_log add column error_class varchar null;
alter table public.event_log add column error_type varchar null;

O impacto que essa versão deve gerar nas aplicações que estavam utilizando a versão 1.x.x será nos métodos de gravação de logs de erros. Os métodos de gravação de log como, por exemplo, ProcessLog.saveError, o parâmetro error, qua anteriormente recebia uma string, passou a receber uma instance de Error.

Implementando response padrão nos controllers

Para utilizar essa funcionalidade é necessário versão 2.1.0 do qq-framework/http ou superior.

Essa implementação visa padronizar os responses dos controllers das aplicações.

Em caso de sucesso, retornando HttpResponseOk e em caso de falha, HttpResponseError

export interface HttpResponseOk {
    data: any;
}

export interface HttpResponseError {
    erro: string;
    message: string;
}
//any.controller.ts

import { Body, Controller, Logger, Post } from '@nestjs/common'
import { AbstractController } from '@qq-framework/ddd'
import { PostarMensagemUseCase } from './application/usecases/PostarMensagem.usecase'
import { CoreModule } from './core.module'


const httpCodeMap: HttpCodeMap = {
    RepositoryException: 400,
}

@Controller('core')
export class CoreController extends AbstractController {
    private readonly logger = new Logger(CoreController.name)

    constructor(private readonly postarMensagemUseCase: PostarMensagemUseCase) {
        super(CoreController.name, CoreModule.name, {
            httpCodeMap,
            defaultHttpCodeErrors: 500,
        })
    }

    @Post('postar-mensagem')
    public async postarMensagem(@Body() params: any) {
        const result = await this.postarMensagemUseCase.execute({
            mensagem: {
                chave: params['chave'],
                conteudo: params['conteudo'],
                headers: params['headers'],
                topico: params['topico'],
            },
        })

        return super.buildResponse({
            data: result,
        })
    }
}

No código visto acima, primeiramente você deve definir quais o códigos HTTP que devem ser retornados para cada exceções possíveis que seu controller retornar para o client, conforme abaixo:

const httpCodeMap: HttpCodeMap = {
    RepositoryException: 400,
}

No construtor do seu controller você deve informar ao AbstractController as configurações dos seus responses HTTP, através da interface HttpResponseConfig

constructor() {
        const httpResponseConfig: HttpResponseConfig = {
            httpCodeMap,
            defaultHttpCodeErrors: 500,
        }
        super(VendaController.name, VendaModule.name, httpResponseConfig)
    }

A propriedade defaultHttpCodeError não é obrigatória, mas serve para indicar qual o http code que o seu controller retornará, caso a exceção não tenha sido mapeada pelo HttpCodeMap. Por default, este valor será 500

Para finalizar, você deve retornar o resultado do seu controller através do método buildResponse. O método buidResponse pode receber, além do parâmetro result, também headers e um parâmetro chamado successStatusCode que será utilizado como código http retornado pelo seu endpoint em caso de sucesso. Ambos os parâmetros são opcionais. Em caso de não informado o successStatusCode, será retornado 200.

    @Post('postar-mensagem')
    public async postarMensagem(@Body() params: any) {
        const result = await this.postarMensagemUseCase.execute({
            mensagem: {
                chave: params['chave'],
                conteudo: params['conteudo'],
                headers: params['headers'],
                topico: params['topico'],
            },
        })

        return super.buildResponse({
            result,
        })
    }

Em caso de sucesso o seu response será retornado para o client com o http code informado em successStatusCode ou 200 (default) e em caso de exceção, ele retornará o httpcode configurado no HttpCodeMap que foi passado no construtor.

Para finalizar, você deve adicionar ao seu projeto o HttpInterceptor disponibilizado no qq-framework/http