Transport EventBus for NestJS
Sergey Telpuk

Sergey Telpuk @sergey_telpuk

About: Experienced PHP/NodeJS/Golang Developer with a demonstrated history of working in the information technology and services industry.

Location:
Minsk
Joined:
Apr 23, 2018

Transport EventBus for NestJS

Publish Date: Dec 17 '19
16 1

Hello friends!
I'm glad to present the library for NestJS. In my article I showed an approach how we can implement transport-eventbus for nestJS but now we can use a done library for it. Go!

nestjs-transport-eventbus allows broadcasting events via variety of nestjs trasports in easy way

Installation

npm i nestjs-transport-eventbus

Quick Start

Import TransportEventBusModule into a willing module, example below:

import { TransportEventBusModule } from 'nestjs-transport-eventbus';

@Module({
    imports: [
        TransportEventBusModule
    ],
    controllers: [AppController],
    providers: [
        AppService
    ],
})
export class AppModule {
}

TransportEventBusModule applies two arguments:\
publishers - array of transport publishers which are based on ClientProxy\
providers - the additional providers for module

Example with RabbitMQ(RabbitPublisher)

For creating a transport publisher there is enough to implement the following steps:
1 Implement RabbitPublisher, example below:\

import { Injectable } from '@nestjs/common';
import { ClientProxy, Transport, Client} from '@nestjs/microservices';
import { Publisher } from 'nestjs-transport-eventbus';

@Injectable()
@Publisher(Transport.RMQ)//Choose the appropriate type of transport in this case `RMQ`
export class RabbitPublisher {
   @Client({
        transport: Transport.RMQ,
        options: {
            urls: ['amqp://rabbit:rabbit@rabbitmq:5672'],
            queue: 'event_service_queue',
            queueOptions: {
                durable: true,
            },
        },
    })
    client: ClientProxy;
}

2 Inject RabbitPublisher into TransportEventBusModule, example below:

import { Module } from '@nestjs/common';
import { TransportEventBusModule } from 'nestjs-transport-eventbus';
import { RabbitPublisher } from '...';

@Module({
    imports: [
        TransportEventBusModule.forRoot({
            publishers: [RabbitPublisher]
        })
    ],
    controllers: [],
    providers: [

    ],
})
export class AppModule {
}

3 Create an event for publisher, example below:

import { TransportType, ExcludeDef } from 'nestjs-transport-eventbus';
import { Transport } from '@nestjs/microservices';

@TransportType(Transport.RMQ)//can apply array of transports, for example RMQ,REDIS
export class RabbitEvent {
    constructor(
        readonly message: string
    ) {
    }
}

Notice: By default, events are handling on both sides broadcasting server and receiving server, for changing this situation add @ExcludeDef() declaration,
can look like below:

....
@TransportType(Transport.RMQ)
@ExcludeDef()
export class RabbitEvent
...

4 Inject TRANSPORT_EVENT_BUS_SERVICE, example below:

import { Inject, Injectable } from '@nestjs/common';
import { TRANSPORT_EVENT_BUS_SERVICE } from 'nestjs-transport-eventbus';
import { IEventBus } from '@nestjs/cqrs';
import { DefaultEvent } from '...';
import { RabbitEvent } from '...'
@Injectable()
export class AppService {
  constructor(
      @Inject(TRANSPORT_EVENT_BUS_SERVICE) private readonly eventBus: IEventBus
  ){

  }
  rabbitEvent(): void {
    this.eventBus.publish(new RabbitEvent('Pass some param'));
  }
}

Notice: Events via AggregateRoot

import { CommandHandler, EventPublisher, ICommandHandler } from '@nestjs/cqrs';
import { TryAggregateRootCommand } from '...';
import { Inject } from '@nestjs/common';
import { TRANSPORT_EVENT_BUS_PUBLISHER } from 'nestjs-transport-eventbus';
import { TestModel } from '...';

@CommandHandler(TryAggregateRootCommand)
export class TryAggregateRootCommandHandler implements ICommandHandler<TryAggregateRootCommand> {
    constructor(
        @Inject(TRANSPORT_EVENT_BUS_PUBLISHER) private readonly publisher: EventPublisher
    ) {
    }

    async execute(command: TryAggregateRootCommand) {
        const {message} = command;
        const aggregator = this.publisher.mergeObjectContext(
            new TestModel()
        );
        aggregator.applyEvent(message);
        aggregator.commit();
    }
}

5 For handling the broadcasted event on receiving side can look like the following:

import { Controller, Inject } from '@nestjs/common';
import { EventPattern } from '@nestjs/microservices';
import { TRANSPORT_EVENT_BUS_PATTERN, TRANSPORT_EVENT_BUS_SERVICE, TransportEvent } from 'nestjs-transport-eventbus';
import { IEvent, IEventBus } from '@nestjs/cqrs';

@Controller()
export class AppService {

  constructor(
      @Inject(TRANSPORT_EVENT_BUS_SERVICE) private readonly eventBus: IEventBus
  ){

  }
  @EventPattern(TRANSPORT_EVENT_BUS_PATTERN)
  handle(@TransportEvent() event: IEvent): void {
    this.eventBus.publish(event);
  }

Notice: TRANSPORT_EVENT_BUS_PATTERN- can pass via .env

Examples

Example is presented two services which communicate with each other via RabbitMQ

Comments 1 total

  • alvitubit
    alvitubitMay 18, 2025

    The nestjs-transport-eventbus library offers a streamlined way to broadcast events across NestJS applications using various transport layers like RabbitMQ, making it perfect for scalable microservices. By importing the TransportEventBusModule, configuring publishers like RabbitPublisher, and defining events such as RabbitEvent, developers can easily implement asynchronous communication. This approach is similar to coordinating a fleet for limo transportation Richmond—you need reliable channels, clearly defined messages (events), and synchronized endpoints (services) to ensure everything moves smoothly. The example illustrates two services using RabbitMQ to communicate, emphasizing modular, decoupled, and efficient event-driven architecture in NestJS.

Add comment