Lifecycle Hooks

Messaging lifecycle hooks allow you to tap into different stages of message processing — from raw input to final handler execution.

They are useful for cross-cutting concerns like logging, tracing, validation, metrics, or custom transformations.

Important: every processed object is treated as immutable. Each stage works on a new instance, rather than mutating the previous one in place.

Important: not every hook is guaranteed to run. Some hooks may be skipped depending on the flow, for example when no handler is registered, processing stops early, or message handling fails before later stages are reached.


Example hook

import {
  HookMessage,
  LifecycleHook,
  MessagingLifecycleHook,
  MessagingLifecycleHookListener,
} from '@nestjstools/messaging';
import { Injectable, Logger } from '@nestjs/common';

@Injectable()
@MessagingLifecycleHook(LifecycleHook.AFTER_MESSAGE_HANDLER_EXECUTION)
export class AfterDenormalizeHook implements MessagingLifecycleHookListener {
  constructor(private readonly logger: Logger) {
  }

  hook(message: HookMessage): Promise<void> {
    this.logger.log(`💡 Here I can do some action ON HOOK | ${message.routingKey}`);
    return Promise.resolve();
  }
}

Lifecycle Overview


Available Hooks

BEFORE_MESSAGE_NORMALIZATION

Executed before the raw incoming message is normalized into the internal messaging format.

Use this hook when you want to:

  • inspect raw transport data,

  • log the original payload,

  • attach tracing or diagnostic metadata before normalization starts.

At this point, the message is still in its original external form.


AFTER_MESSAGE_NORMALIZATION

Executed after the raw message has been normalized into the internal messaging representation.

Use this hook when you want to:

  • inspect the normalized structure,

  • validate normalized metadata,

  • enrich processing context based on the normalized message.

At this stage, the system has already transformed the transport payload into the unified internal format.


AFTER_MESSAGE_DENORMALIZED

Executed after the normalized message has been denormalized into the target application object.

Use this hook when you want to:

  • inspect the final typed message object,

  • perform additional validation on the resolved message instance,

  • log the exact object that will be passed further into the pipeline.

This is usually the first point where you work with the final application-level message object instead of transport or normalized data.


BEFORE_MESSAGE_HANDLER

Executed right before the handler is invoked.

Use this hook when you want to:

  • run last-step checks before handling,

  • prepare contextual logging,

  • inspect the message object that is about to be processed by the handler.

This hook is triggered after denormalization and before middleware / handler execution begins.


AFTER_MESSAGE_HANDLER_EXECUTION

Executed after the handler finishes successfully.

Use this hook when you want to:

  • log successful processing,

  • measure execution results,

  • trigger post-processing actions after handler completion.

This hook is only executed when the handler completes without throwing an exception.


ON_CONSUMER_HANDLED_MESSAGE

Executed when a consumer has successfully handled the message.

Use this hook when you want to:

  • emit success metrics,

  • store processing audit entries,

  • mark the message as fully processed.

This is a success-only hook and is typically one of the last lifecycle points in the handling flow.


ON_FAILED_MESSAGE_CONSUMER

Executed when message consumption fails due to an exception during processing.

Use this hook when you want to:

  • log failures,

  • send alerts,

  • store error details,

  • trigger retry or dead-letter related logic.

This hook is only executed for failed processing paths.

Last updated

Was this helpful?