Skip to content

ListenersController

reference
1 min readUpdated

Kind: Class

Source: packages/microservices/listeners-controller.ts

Part of: Microservices

ListenersController is an internal NestJS microservices component that discovers @MessagePattern() and @EventPattern() handlers on controllers and registers them with a microservice server. It also resolves request-scoped handlers, attaches client proxies to decorated properties, and normalizes handler results into RxJS observables for transport processing.

Methods

MethodSignatureReturns
registerPatternHandlersregisterPatternHandlers(instanceWrapper: InstanceWrapper<Controller>, serverInstance: Server, moduleKey: string)void
insertEntrypointDefinition`insertEntrypointDefinition(instanceWrapper: InstanceWrapper, definition: EventOrMessageListenerDefinition, transportId: Transportsymbol)`
forkJoinHandlersIfAttached`forkJoinHandlersIfAttached(currentReturnValue: PromiseObservable, originalArgs: unknown[], handlerRef: MessageHandler)`
assignClientsToPropertiesassignClientsToProperties(instance: Controller)void
assignClientToInstanceassignClientToInstance(instance: Controller, property: string, client: T)void
createRequestScopedHandlercreateRequestScopedHandler(wrapper: InstanceWrapper, pattern: PatternMetadata, moduleRef: Module, moduleKey: string, methodKey: string, defaultCallMetadata: Record<string, any>, isEventHandler: undefined)void
transformToObservable`transformToObservable(resultOrDeferred: ObservablePromise)`
transformToObservabletransformToObservable(resultOrDeferred: T)never extends Observable<ObservedValueOf<T>> ? Observable<T> : Observable<ObservedValueOf<T>>
transformToObservabletransformToObservable(resultOrDeferred: any)void

Where it refuses work

  • ListenersController stops the work with an early return when isEventHandler.
  • ListenersController stops the work with an early return when resultOrDeferred instanceof Promise.
  • ListenersController stops the work with an early return when isObservable(resultOrDeferred).

When something fails

  • ListenersController handles failure in 1 place: it turns it into a return value in all 1.

Diagram

mermaid
graph LR
  A[Nest application bootstrap] --> B[ListenersController]
  B --> C[Discover controller methods]
  C --> D[Read message/event pattern metadata]
  D --> E[Register handlers on microservice server]
  E --> F[Request-scoped handler creation]
  E --> G[Observable response stream]
  B --> H[Assign @Client() proxies to properties]
  H --> I[Controller instances]

Usage

ts
import { Controller } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import {
  ClientProxy,
  ClientProxyFactory,
  MessagePattern,
  Transport,
} from '@nestjs/microservices';
import { AppModule } from './app.module';

@Controller()
class OrdersController {
  // In normal applications, ListenersController assigns this proxy
  // when using Nest's @Client() decorator and module metadata.
  private readonly billingClient: ClientProxy = ClientProxyFactory.create({
    transport: Transport.TCP,
  });

  @MessagePattern({ cmd: 'get-order' })
  getOrder(orderId: string) {
    return {
      id: orderId,
      status: 'confirmed',
    };
  }

  @MessagePattern({ cmd: 'stream-order-events' })
  streamOrderEvents() {
    return this.billingClient.send({ cmd: 'order-events' }, {});
  }
}

async function bootstrap() {
  const app = await NestFactory.createMicroservice(AppModule, {
    transport: Transport.TCP,
  });

  // During startup, Nest internally uses ListenersController to
  // discover and register @MessagePattern() handlers.
  await app.listen();
}

bootstrap();

AI Coding Instructions

  • Treat ListenersController as framework infrastructure; applications should register handlers through @MessagePattern() and @EventPattern() rather than instantiating this class directly.
  • Preserve observable normalization when changing handler invocation logic: handlers may return plain values, promises, or RxJS observables.
  • Keep request-scoped handlers isolated by using the request context and scoped provider resolution path rather than reusing singleton controller instances.
  • When adding transport integrations, ensure every discovered pattern is registered with the server and that attached event handlers are joined/forked correctly.
  • Maintain client-property assignment behavior for controller instances using Nest microservice client proxy metadata.

Relationships

  • IMPORTS → Controller
  • IMPORTS → isUndefined
  • IMPORTS → ContextIdFactory
  • IMPORTS → ExecutionContextHost
  • IMPORTS → STATIC_CONTEXT
  • IMPORTS → NestContainer
  • IMPORTS → Injector
  • IMPORTS → ContextId
  • IMPORTS → InstanceWrapper
  • IMPORTS → Module
  • IMPORTS → GraphInspector
  • IMPORTS → MetadataScanner
  • IMPORTS → REQUEST_CONTEXT_ID

Was this page helpful?

Download as PDF
ListenersController — NestJS head-to-head