DEV Community

Sergey Telpuk
Sergey Telpuk

Posted on

8 1

Nestjs, External EventBus

Hello friends! In this article, I wanna share one solution to implementing external EventBus. if you haven't been acquainted with EventBus yet, you can visit this link.
By default, Nestjs allows calling event handler only locally. It's a problem when we want to publish events via external EventBus, so I suggest the following solution. Bellow, I'll show a publisher which is based on redis-pub. Also, we can find a publisher for RabbitMQ.

RedisPublisher.

import {Injectable} from '@nestjs/common';
import {Client, ClientProxy, Transport} from '@nestjs/microservices';
import {AbstractPublisher} from '../abstract.publisher';


@Injectable()
export class RedisPublisher extends AbstractPublisher {
    TRANSPORT = Transport.REDIS;
    PATTERN = 'event_bus';

    @Client({
        transport: Transport.REDIS,
        options: {
            url: 'redis://:password123@redis:6379',
        },
    })
    client: ClientProxy;

    protected async send(pattern: any, data: any) {
        try {
            await this.client.send(pattern, data).toPromise();
        } catch (e) {
            this.log.error(e);
        }
    }
}

AbstractPublisher

import {IEvent, IEventPublisher} from '@nestjs/cqrs';
import {Transport} from './transport.enum';
import {Injectable, Logger} from '@nestjs/common';

@Injectable()
export abstract class AbstractPublisher implements IEventPublisher {
    abstract TRANSPORT: Transport;
    abstract PATTERN: string;

    constructor(
        protected readonly log: Logger,
    ) {

    }

    publish<T extends IEvent>(event: T): void {

        const data = {
            payload: event,
            event: event.constructor.name,
        };

        this.send(this.PATTERN, data);
    }

    protected abstract send(pattern: any, data: any): any;
}

As you can see, RedisPublisher extends AbstractPublisher where is required to implement the send method. For a particular type of transport, we should implement own send method and add transport into the event. In common case, it's enough to start sending an event via transport.

ContrivedEvent

export class ContrivedEvent implements IEventWithTransport {
    TRANSPORTS = [Transport.RMQ, Transport.DEF, Transport.REDIS];

    constructor(
    ) {}
}
...
import {IEvent} from '@nestjs/cqrs';
import {Transport} from '../transport.enum';

export interface IEventWithTransport extends IEvent {
    TRANSPORTS: Transport[];
}
...

export enum Transport {
    TCP = 0,
    REDIS = 1,
    NATS = 2,
    MQTT = 3,
    GRPC = 4,
    RMQ = 5,
    DEF = 6,
}

As you can see, there were used three kinds of transports:

  1. RabitMQ
  2. Redis
  3. Local

Using EventBusTransport:

import {Controller, Get} from '@nestjs/common';
import {EventBusTransport} from '../event-bus-transport/event.bus.transport';
import {ContrivedEvent} from '../events/contrived/contrived.event';

@Controller('/')
export class ContrivedController {

    constructor(
        readonly eventBusTransport: EventBusTransport,
    ) {}

    @Get('/contrived')
     contrived() {
        this.eventBusTransport.publish(new ContrivedEvent());
    }

}

AWS Q Developer image

Your AI Code Assistant

Generate and update README files, create data-flow diagrams, and keep your project fully documented. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

Top comments (1)

Collapse
 
cyberluke profile image
Lukas Satin •

Hi, this should be on official Nest website. I don't get their EventBus. They want microservices, they want CQRS and then they suck it on local EventBus. Why??? I spend whole day googling why. From what I understand CQRS is evil (even Fowler mentions it is not for 90% of projects)

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

👋 Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay