> For the complete documentation index, see [llms.txt](https://docs.nestjstools.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nestjstools.com/components/message-handlers.md).

# Message Handlers

## 📦 Message Handlers

Message handlers define how your application reacts to specific messages dispatched on a bus. They encapsulate business logic triggered by inter-service or internal communication.

This page explains how to define, register, and work with message handlers using `@nestjstools/messaging`.

***

### 🛠️ Defining a Message Handler

A message handler is a class that implements the `IMessageHandler<T>` interface for a specific message type.

#### Example:

```ts
import { Injectable } from '@nestjs/common';
import { MessageHandler, IMessageHandler, MessageResponse } from '@nestjstools/messaging';
import { SendMessage } from './send-message';

@Injectable()
@MessageHandler('your.message')
export class SendMessageHandler implements IMessageHandler<SendMessage> {
  async handle(message: SendMessage): Promise<MessageResponse | void> {
    console.log(message.content);
    // Your business logic here
  }
}
```

***

### 🔁 MessageHandler routing keys and priority

`@MessageHandler` supports **two ways** of defining routing keys.

#### 🔹 Direct routing keys

Use the decorator arguments when you only need to define routing keys.

**Single routing key**

```ts
@MessageHandler('your.message')
```

**Multiple routing keys**

```ts
@MessageHandler('your.message', 'alternate.route')
```

#### ⚙️ Configuration form

Use the configuration object when you also want to define handler priority.

**Single routing key**

```ts
@MessageHandler({
  routingKey: 'your.message',
  priority: 10,
})
```

**Multiple routing keys**

```ts
@MessageHandler({
  routingKey: ['your.message', 'alternate.route'],
  priority: 10,
})
```

#### 🚦 Handler priority

`routingKey` accepts either:

```ts
string | string[]
```

`priority` is optional and defaults to:

```ts
priority: 0
```

When multiple handlers listen to the same routing key:

* ⬆️ **Higher-priority handlers run first**
* ⬇️ Lower-priority handlers run after higher-priority handlers complete
* ⚡ Handlers with the **same priority run in parallel**

For example:

```ts
@MessageHandler({
  routingKey: 'order.created',
  priority: 20,
})
handleCriticalOrderLogic() {}

@MessageHandler({
  routingKey: 'order.created',
  priority: 10,
})
handleSecondaryLogic() {}

@MessageHandler({
  routingKey: 'order.created',
  priority: 10,
})
handleAnalytics() {}
```

Execution order:

```
priority 20
    ↓
priority 10 ──┬── handleSecondaryLogic()
              └── handleAnalytics()
                  (executed in parallel)
```

***

### 🧠 Typed Message Input with `@DenormalizeMessage()`

By default, the handler receives the raw message data (usually as a plain JavaScript object). If you want to receive it as a properly instantiated class, use the `@DenormalizeMessage()` decorator:

```ts
async handle(@DenormalizeMessage() message: SendMessage): Promise<void> {
  // Now message is an instance of SendMessage with all class logic available
}
```

This is especially helpful when your message class contains methods, getters, or requires validation logic.

***

### 🧩 Registering Handlers

Handlers are automatically discovered by NestJS as long as they are included in the providers of a module:

```ts
@Module({
  providers: [SendMessageHandler],
})
export class MessagingFeatureModule {}
```

If you use a feature module, ensure that the module is imported by the root module and that `MessagingModule` is globally available or also imported.

***

### 📤 Triggering Handlers

Handlers respond to messages dispatched through a message bus with a matching route:

```ts
await messageBus.dispatch(
  new RoutingMessage(new SendMessage('Hello!'), 'your.message'),
);
```

If a handler is decorated with `@MessageHandler('your.message')`, it will receive this message.

***

### Returning a Response

Handlers can return a `MessageResponse` if needed:

```ts
import { MessageResponse } from '@nestjstools/messaging';

return new MessageResponse({ result: 'OK' });
```

You can optionally implement response-handling logic in the calling component.

***

### Summary

| Concept                 | Description                                                                         |
| ----------------------- | ----------------------------------------------------------------------------------- |
| `@MessageHandler()`     | Binds a handler to one or more routes                                               |
| `IMessageHandler<T>`    | Interface for handling a specific message type                                      |
| `@DenormalizeMessage()` | Automatically deserializes message into class instance                              |
| `MessageResponse`       | Optional way to return structured results from handlers, you can also return object |

***

{% hint style="info" %}
Note that handlers are visible across channels
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.nestjstools.com/components/message-handlers.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
