typescriptrabbitmqnestjsmessage-queue

NestJS @EventPattern with RMQ topic exchange does not create binding (no bindingKeys, custom exchange)


I’ve created a service in NestJS and connected it to RabbitMQ. The connection is established successfully, but I don’t receive any messages unless I manually add a binding in the RabbitMQ Management UI.

What am I missing in my configuration that would allow NestJS to automatically create the binding?


My main.ts

import 'reflect-metadata';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const rabbitUser = process.env.RABBIT_USER ?? 'username';
  const rabbitPass = encodeURIComponent(process.env.RABBIT_PASS ?? 'pass');
  const rabbitHost = process.env.RABBIT_HOST ?? '192.168.178.39:5672';

  // RabbitMQ-Microservice zum App-Prozess hinzufügen
  app.connectMicroservice<MicroserviceOptions>({
    transport: Transport.RMQ,
    options: {
      urls: [`amqp://${rabbitUser}:${rabbitPass}@${rabbitHost}`],
      queue: 'user-service-queue1',
      queueOptions: { durable: false },
      exchange: 'amq.topic',
      noAck: false,
    },
  });

  ...

  await app.listen(process.env.PORT ?? 3000, '0.0.0.0');
}

bootstrap();

My Consumer

import { Controller } from '@nestjs/common';
import { EventPattern, Payload, Ctx, RmqContext } from '@nestjs/microservices';

@Controller()
export class UserEventConsumer {

  constructor() {
    console.log('✅ UserEventConsumer initialized');
  }

  /**
   * Handle broadcast events for user creation
   */
  @EventPattern('user.created')
  async handleUserCreated(@Payload() data: any, @Ctx() context: RmqContext) {
    console.log('[✅ Event received] user.created:', data);
    context.getChannelRef().ack(context.getMessage());
  }
}

My user.module

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { UserRepository } from './user.repository';
import { UserEntity } from './entities/user.entity';
import { UserEventConsumer } from './user-event.consumer';

@Module({
  imports: [TypeOrmModule.forFeature([UserEntity])],
  controllers: [UserController, UserEventConsumer],
  providers: [UserRepository, UserService],
})
export class UserModule {}

And this is my RabbitMQ UI:

Here you can see that I manually added the binding: Exchange: amq.topic → Routing key: user.created. Then everything works. But without that manual step, the service only creates the queue, not the binding.

I want NestJS to automatically create the binding when the app starts.


Solution

  • On main.ts you need to do

    await app.startAllMicroservices();
    

    before the app.listen()

    You can see the example in the Official docs