@nestjstools/messaging 4.1.0-beta.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -72
- package/lib/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -4,21 +4,30 @@
|
|
|
4
4
|
|
|
5
5
|
# NestJS Messaging Library - Message Bus & Service Bus for Distributed Systems
|
|
6
6
|
|
|
7
|
-
A NestJS library for managing asynchronous and synchronous messages (service bus) with support for buses, handlers,
|
|
7
|
+
A NestJS library for managing asynchronous and synchronous messages (service bus) with support for buses, handlers,
|
|
8
|
+
channels, and consumers. This library simplifies building scalable and decoupled applications by facilitating robust
|
|
9
|
+
message handling pipelines while ensuring flexibility and reliability.
|
|
8
10
|
|
|
9
11
|
---
|
|
10
12
|
|
|
11
13
|
## Features
|
|
14
|
+
|
|
12
15
|
- **Message Buses**: Define multiple buses for commands, events, and queries to streamline message routing.
|
|
13
16
|
- **Handlers**: Easily register and manage handlers for processing messages.
|
|
14
|
-
- **Channels**: Support for in-memory channels and **easy extension** to create custom channel implementations tailored
|
|
15
|
-
|
|
16
|
-
- **
|
|
17
|
+
- **Channels**: Support for in-memory channels and **easy extension** to create custom channel implementations tailored
|
|
18
|
+
to your needs.
|
|
19
|
+
- **Consumers**: Run message consumers to process queued messages asynchronously, ensuring system reliability and fault
|
|
20
|
+
tolerance.
|
|
21
|
+
- **Middleware Support**: Add custom middleware for message transformation such like validation, logging - do whatever
|
|
22
|
+
you want.
|
|
17
23
|
- **Debug Mode**: Enable enhanced logging and debugging capabilities for development.
|
|
18
|
-
- **Extensibility**: Creating new channels is straightforward, allowing developers to expand and integrate with external
|
|
19
|
-
|
|
24
|
+
- **Extensibility**: Creating new channels is straightforward, allowing developers to expand and integrate with external
|
|
25
|
+
systems or protocols effortlessly.
|
|
26
|
+
- **Concurrent Handler Execution**: Messages dispatched to multiple handlers are processed concurrently, improving
|
|
27
|
+
performance and responsiveness across your system.
|
|
20
28
|
|
|
21
29
|
## Channels
|
|
30
|
+
|
|
22
31
|
- [Redis channel adapter](https://www.npmjs.com/package/@nestjstools/messaging-redis-extension)
|
|
23
32
|
- [RabbitMQ channel adapter](https://www.npmjs.com/package/@nestjstools/messaging-rabbitmq-extension)
|
|
24
33
|
- [Amazon SQS channel adapter](https://www.npmjs.com/package/@nestjstools/messaging-amazon-sqs-extension)
|
|
@@ -81,7 +90,8 @@ import { SendMessageHandler } from './handlers/send-message.handler';
|
|
|
81
90
|
}),
|
|
82
91
|
],
|
|
83
92
|
})
|
|
84
|
-
export class AppModule {
|
|
93
|
+
export class AppModule {
|
|
94
|
+
}
|
|
85
95
|
```
|
|
86
96
|
|
|
87
97
|
### Define a Message & Message Handler
|
|
@@ -89,6 +99,7 @@ export class AppModule {}
|
|
|
89
99
|
Create a new handler that processes specific message
|
|
90
100
|
|
|
91
101
|
#### Define your message
|
|
102
|
+
|
|
92
103
|
```typescript
|
|
93
104
|
export class SendMessage {
|
|
94
105
|
constructor(
|
|
@@ -98,7 +109,9 @@ export class SendMessage {
|
|
|
98
109
|
}
|
|
99
110
|
|
|
100
111
|
```
|
|
112
|
+
|
|
101
113
|
#### Define your message handler
|
|
114
|
+
|
|
102
115
|
```typescript
|
|
103
116
|
import { SendMessage } from './send-message';
|
|
104
117
|
import { MessageResponse, MessageHandler, IMessageHandler } from '@nestjstools/messaging';
|
|
@@ -108,9 +121,9 @@ import { Injectable } from '@nestjs/common';
|
|
|
108
121
|
@Injectable()
|
|
109
122
|
@MessageHandler('your.message')
|
|
110
123
|
export class SendMessageHandler implements IMessageHandler<SendMessage> {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
124
|
+
// If you want to receive the message as a properly typed instance (not just a raw object),
|
|
125
|
+
// use the `@DenormalizeMessage()` decorator on the parameter:
|
|
126
|
+
// async handle(@DenormalizeMessage() message: SendMessage): Promise<MessageResponse | void> {
|
|
114
127
|
|
|
115
128
|
async handle(message: SendMessage): Promise<object | void> {
|
|
116
129
|
console.log(message.content);
|
|
@@ -121,7 +134,8 @@ export class SendMessageHandler implements IMessageHandler<SendMessage> {
|
|
|
121
134
|
|
|
122
135
|
### Next Step: Dispatching a Message
|
|
123
136
|
|
|
124
|
-
Messages can be dispatched from anywhere in your application—whether from services, controllers, or other components.
|
|
137
|
+
Messages can be dispatched from anywhere in your application—whether from services, controllers, or other components.
|
|
138
|
+
Here’s an example using an HTTP endpoint:
|
|
125
139
|
|
|
126
140
|
```typescript
|
|
127
141
|
import { Controller, Get } from '@nestjs/common';
|
|
@@ -132,7 +146,8 @@ import { SendMessage } from './test/send-message';
|
|
|
132
146
|
@Controller()
|
|
133
147
|
export class AppController {
|
|
134
148
|
//You can inject every bus which you defined in configuration
|
|
135
|
-
constructor(@MessageBus('message.bus') private readonly messageBus: IMessageBus) {
|
|
149
|
+
constructor(@MessageBus('message.bus') private readonly messageBus: IMessageBus) {
|
|
150
|
+
}
|
|
136
151
|
|
|
137
152
|
@Get()
|
|
138
153
|
async dispatchMessage(): Promise<string> {
|
|
@@ -149,28 +164,39 @@ export class AppController {
|
|
|
149
164
|
### Flow:
|
|
150
165
|
|
|
151
166
|
1. **Flexible Dispatching**:
|
|
152
|
-
- You can call the `dispatch` method from any layer (e.g., controller, service, or scheduled job). This example uses
|
|
167
|
+
- You can call the `dispatch` method from any layer (e.g., controller, service, or scheduled job). This example uses
|
|
168
|
+
an HTTP `GET` endpoint for demonstration.
|
|
153
169
|
|
|
154
170
|
2. **`@MessageBus` Decorator**:
|
|
155
171
|
- Injects the particular message bus (identified by its name, `message.bus`) into the `AppController`.
|
|
156
172
|
|
|
157
173
|
3. **Routing and Payload**:
|
|
158
|
-
- Wrap the payload (`SendMessage`) in a `RoutingMessage` to specify its route (`your.message`), which ensures the
|
|
159
|
-
|
|
174
|
+
- Wrap the payload (`SendMessage`) in a `RoutingMessage` to specify its route (`your.message`), which ensures the
|
|
175
|
+
message is handled by the appropriate handler.
|
|
176
|
+
|
|
160
177
|
4. **HTTP Trigger**:
|
|
161
|
-
- This implementation illustrates an entry point triggered via an HTTP request, showcasing how simple it is to
|
|
178
|
+
- This implementation illustrates an entry point triggered via an HTTP request, showcasing how simple it is to
|
|
179
|
+
connect the messaging system to a web interface.
|
|
162
180
|
|
|
163
181
|
### ⚠️ Warning!
|
|
164
|
-
🚨 Important Notice: You can **return responses from handlers**, but currently, it only works with the `InMemoryChannel`. This behavior may not function as expected if multiple handlers are processing a single message.
|
|
165
182
|
|
|
166
|
-
|
|
183
|
+
🚨 Important Notice: You can **return responses from handlers**, but currently, it only works with the `InMemoryChannel`.
|
|
184
|
+
This behavior may not function as expected if multiple handlers are processing a single message.
|
|
185
|
+
|
|
186
|
+
🛠️ Please ensure you're using a compatible setup when working with multiple handlers, as this could result in unexpected
|
|
187
|
+
behavior.
|
|
167
188
|
|
|
168
189
|
---
|
|
190
|
+
|
|
169
191
|
## Normalizers
|
|
192
|
+
|
|
170
193
|
What is a Normalizer?
|
|
171
|
-
A Normalizer is a component that transforms messages between different formats. It ensures that messages are correctly
|
|
194
|
+
A Normalizer is a component that transforms messages between different formats. It ensures that messages are correctly
|
|
195
|
+
encoded when sent and properly decoded when received. This is particularly useful in messaging systems where messages
|
|
196
|
+
need to be serialized and deserialized efficiently.
|
|
172
197
|
|
|
173
198
|
You can use it to make it works with:
|
|
199
|
+
|
|
174
200
|
* [protobuf](https://protobuf.dev/)
|
|
175
201
|
* Custom JSONs
|
|
176
202
|
* Base64
|
|
@@ -198,10 +224,15 @@ export class Base64Normalizer implements MessageNormalizer {
|
|
|
198
224
|
}
|
|
199
225
|
|
|
200
226
|
```
|
|
227
|
+
|
|
201
228
|
### How It Works
|
|
229
|
+
|
|
202
230
|
#### Normalization (normalize)
|
|
231
|
+
|
|
203
232
|
* Converts a JSON object to a Base64 string before sending.
|
|
233
|
+
|
|
204
234
|
#### Denormalization (denormalize)
|
|
235
|
+
|
|
205
236
|
* Decodes the Base64 string back into a JSON object after receiving.
|
|
206
237
|
|
|
207
238
|
You can define a **Normalizer** per Channel
|
|
@@ -209,15 +240,20 @@ ___
|
|
|
209
240
|
|
|
210
241
|
## ⤵️ Middlewares
|
|
211
242
|
|
|
212
|
-
A **middleware** in the context of the `MessagingModule` is a function that processes messages as they pass through the
|
|
243
|
+
A **middleware** in the context of the `MessagingModule` is a function that processes messages as they pass through the
|
|
244
|
+
message pipeline. The middleware can intercept, modify, or log messages before they are handled by the respective *
|
|
245
|
+
*message handler**. This is particularly useful for logging, authentication, validation, or any other pre-processing
|
|
246
|
+
step before the actual business logic is applied.
|
|
213
247
|
|
|
214
|
-
Each **channel** in the messaging system has its own set of middlewares, and these middlewares are executed in order
|
|
248
|
+
Each **channel** in the messaging system has its own set of middlewares, and these middlewares are executed in order
|
|
249
|
+
when a message is dispatched through the respective channel.
|
|
215
250
|
|
|
216
251
|
### How to Use Middleware in Messaging Channels:
|
|
217
252
|
|
|
218
253
|
To use middleware, you need to:
|
|
219
254
|
|
|
220
|
-
1. **Define the middleware class** that implements the `Middleware` interface, which contains the `process` method that
|
|
255
|
+
1. **Define the middleware class** that implements the `Middleware` interface, which contains the `process` method that
|
|
256
|
+
processes the message.
|
|
221
257
|
2. **Attach the middleware to a specific channel** via the channel configuration.
|
|
222
258
|
|
|
223
259
|
### Example Middleware Code:
|
|
@@ -231,17 +267,18 @@ import { Middleware, RoutingMessage } from '@nestjstools/messaging';
|
|
|
231
267
|
@Injectable()
|
|
232
268
|
@MessagingMiddleware()
|
|
233
269
|
export class TestMiddleware implements Middleware {
|
|
234
|
-
|
|
235
|
-
|
|
270
|
+
async process(message: RoutingMessage, context: MiddlewareContext): Promise<MiddlewareContext> {
|
|
271
|
+
console.log('!!!! WORKS'); // Log or process the message here
|
|
236
272
|
|
|
237
|
-
|
|
238
|
-
|
|
273
|
+
return await context.next().process(message, context); //TODO call `next()` method from `MiddlewareContext` to process next middleware
|
|
274
|
+
}
|
|
239
275
|
}
|
|
240
276
|
```
|
|
241
277
|
|
|
242
278
|
### Attaching Middleware to a Channel:
|
|
243
279
|
|
|
244
|
-
Now that we've defined the middleware, it needs to be attached to a specific channel in the `MessagingModule`
|
|
280
|
+
Now that we've defined the middleware, it needs to be attached to a specific channel in the `MessagingModule`
|
|
281
|
+
configuration. Here's how you would configure the middleware for a channel:
|
|
245
282
|
|
|
246
283
|
```typescript
|
|
247
284
|
import { MessagingModule, AmqpChannelConfig, InMemoryChannelConfig } from '@nestjstools/messaging';
|
|
@@ -278,48 +315,60 @@ import { SendMessageHandler } from './handlers/send-message.handler';
|
|
|
278
315
|
}),
|
|
279
316
|
],
|
|
280
317
|
})
|
|
281
|
-
export class AppModule {
|
|
318
|
+
export class AppModule {
|
|
319
|
+
}
|
|
282
320
|
```
|
|
283
321
|
|
|
284
322
|
### Explanation of How It Works:
|
|
285
323
|
|
|
286
324
|
1. **Middleware Class**:
|
|
287
|
-
- A `Middleware` is a class that implements the `next` method. In this case, the `TestMiddleware` simply logs
|
|
325
|
+
- A `Middleware` is a class that implements the `next` method. In this case, the `TestMiddleware` simply logs
|
|
326
|
+
`'!!!! WORKS'` and allows the message to continue.
|
|
288
327
|
|
|
289
328
|
2. **Message Pipeline**:
|
|
290
329
|
- When a message is dispatched, it passes through the series of middlewares configured for its channel.
|
|
291
|
-
- The middlewares execute in the order they're listed for the channel, and each `next` method decides what happens
|
|
330
|
+
- The middlewares execute in the order they're listed for the channel, and each `next` method decides what happens
|
|
331
|
+
to the message—whether it continues or gets transformed.
|
|
292
332
|
|
|
293
333
|
3. **Channel-Specific Middlewares**:
|
|
294
|
-
- Each channel can have its own set of middlewares defined in the channel's configuration (e.g.,
|
|
295
|
-
|
|
334
|
+
- Each channel can have its own set of middlewares defined in the channel's configuration (e.g.,
|
|
335
|
+
`InMemoryChannelConfig` and `AmqpChannelConfig`).
|
|
336
|
+
- This allows flexible control of how messages are processed depending on the channel, enabling different logic for
|
|
337
|
+
each transport mechanism (in-memory vs. RabbitMQ).
|
|
296
338
|
|
|
297
339
|
### Benefits of Using Middlewares:
|
|
298
|
-
|
|
340
|
+
|
|
341
|
+
- **Separation of Concerns**: Middlewares help encapsulate cross-cutting concerns like logging, validation, and
|
|
342
|
+
authentication, making the code cleaner.
|
|
299
343
|
- **Reusability**: A middleware can be reused across different channels to perform the same actions on various messages.
|
|
300
|
-
- **Custom Logic**: You can apply custom transformations, logging, or other types of business logic to messages as they
|
|
344
|
+
- **Custom Logic**: You can apply custom transformations, logging, or other types of business logic to messages as they
|
|
345
|
+
move through the pipeline.
|
|
301
346
|
|
|
302
347
|
---
|
|
303
348
|
|
|
304
349
|
## 🔰 ExceptionListener
|
|
305
350
|
|
|
306
|
-
The **ExceptionListener** provides a centralized way to handle exceptions thrown during asynchronous message processing
|
|
351
|
+
The **ExceptionListener** provides a centralized way to handle exceptions thrown during asynchronous message processing
|
|
352
|
+
from any **channel** in your **messaging system**.
|
|
307
353
|
|
|
308
|
-
By decorating a class with `@MessagingExceptionListener()` and implementing the `ExceptionListener` interface, you can
|
|
354
|
+
By decorating a class with `@MessagingExceptionListener()` and implementing the `ExceptionListener` interface, you can
|
|
355
|
+
intercept and respond to any unhandled exception occurring during message handling — whether it's logging, reporting,
|
|
356
|
+
retries, or custom recovery logic.
|
|
309
357
|
|
|
310
358
|
Example Use Case:
|
|
311
359
|
You can log the error, send a notification, or trigger fallback logic whenever a message handler throws an exception.
|
|
312
360
|
|
|
313
361
|
### Example ExceptionListener Code:
|
|
362
|
+
|
|
314
363
|
```typescript
|
|
315
364
|
import { Injectable } from '@nestjs/common';
|
|
316
365
|
import { ExceptionListener, MessagingExceptionListener, ExceptionContext } from '@nestjstools/messaging';
|
|
317
366
|
|
|
318
367
|
@MessagingExceptionListener()
|
|
319
368
|
export class CustomExceptionListener implements ExceptionListener {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
369
|
+
onException(context: ExceptionContext): Promise<void> {
|
|
370
|
+
console.log(`Here I can handle exception If I want and do some action`);
|
|
371
|
+
}
|
|
323
372
|
}
|
|
324
373
|
```
|
|
325
374
|
|
|
@@ -335,45 +384,55 @@ A custom logger must implement the interface `MessagingLogger` interface:
|
|
|
335
384
|
### Providing a custom logger
|
|
336
385
|
|
|
337
386
|
When configuring the **messaging module**, you can pass your own logger instance via options `customLogger`.
|
|
387
|
+
|
|
338
388
|
```ts
|
|
389
|
+
|
|
339
390
|
@Module({
|
|
340
391
|
imports: [
|
|
341
392
|
MessagingModule.forRoot({
|
|
342
393
|
customLogger: new MyCustomLogger(),
|
|
343
|
-
|
|
394
|
+
...
|
|
344
395
|
}),
|
|
345
396
|
],
|
|
346
397
|
})
|
|
347
|
-
export class AppModule {
|
|
398
|
+
export class AppModule {
|
|
399
|
+
}
|
|
348
400
|
```
|
|
401
|
+
|
|
349
402
|
or if you defined it as provider
|
|
403
|
+
|
|
350
404
|
```ts
|
|
405
|
+
|
|
351
406
|
@Module({
|
|
352
407
|
imports: [
|
|
353
408
|
MessagingModule.forRoot({
|
|
354
409
|
customLogger: MyCustomLogger,
|
|
355
|
-
|
|
410
|
+
...
|
|
356
411
|
}),
|
|
357
412
|
],
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
413
|
+
providers: [
|
|
414
|
+
MyCustomLogger,
|
|
415
|
+
],
|
|
361
416
|
})
|
|
362
|
-
export class AppModule {
|
|
417
|
+
export class AppModule {
|
|
418
|
+
}
|
|
363
419
|
```
|
|
364
420
|
|
|
365
421
|
## Configuration options
|
|
366
422
|
|
|
367
423
|
### `MessagingModule.forRoot` Configuration
|
|
424
|
+
|
|
368
425
|
<br>
|
|
369
426
|
|
|
370
|
-
| **Property**
|
|
371
|
-
|
|
372
|
-
| **`buses`**
|
|
373
|
-
| **`channels`**
|
|
374
|
-
| **`debug`**
|
|
375
|
-
| **`logging`**
|
|
376
|
-
| **`customLogger`**
|
|
427
|
+
| **Property** | **Description** | **Default Value** |
|
|
428
|
+
|--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------|
|
|
429
|
+
| **`buses`** | Array of message buses that define routing and processing of messages. | `[]` (empty array by default) |
|
|
430
|
+
| **`channels`** | Array of channel configurations used by the message buses. | `[]` (empty array by default) |
|
|
431
|
+
| **`debug`** | Enables or disables debug mode for logging additional messages. | `false` |
|
|
432
|
+
| **`logging`** | Enables or disables logging for bus activity (e.g., message dispatch). | `true` |
|
|
433
|
+
| **`customLogger`** | Instance of a class implements `MessagingLogger` for custom logging integration. | `NestLogger` |
|
|
434
|
+
| **`forceDisableAllConsumers`** | Forces all messaging consumers to be disabled. Messages can only be processed through the `InMemoryChannel`. Useful in testing environments to prevent external transports or background consumers from running. | `false` |
|
|
435
|
+
|
|
377
436
|
---
|
|
378
437
|
|
|
379
438
|
### Buses
|
|
@@ -389,18 +448,24 @@ export class AppModule {}
|
|
|
389
448
|
|
|
390
449
|
#### **InMemoryChannelConfig**
|
|
391
450
|
|
|
392
|
-
| **Property** | **Description**
|
|
393
|
-
|
|
394
|
-
| **`name`** | Name of the in-memory channel (e.g., `'my-channel'`).
|
|
395
|
-
| **`middlewares`** | List of middlewares to apply to the channel.
|
|
396
|
-
| **`avoidErrorsForNotExistedHandlers`** | Avoid errors if no handler is available for the message.
|
|
397
|
-
| **`normalizer`** | Set your custom normalizer for messages
|
|
451
|
+
| **Property** | **Description** | **Default Value** |
|
|
452
|
+
|----------------------------------------|----------------------------------------------------------|-------------------|
|
|
453
|
+
| **`name`** | Name of the in-memory channel (e.g., `'my-channel'`). | |
|
|
454
|
+
| **`middlewares`** | List of middlewares to apply to the channel. | `[]` |
|
|
455
|
+
| **`avoidErrorsForNotExistedHandlers`** | Avoid errors if no handler is available for the message. | `false` |
|
|
456
|
+
| **`normalizer`** | Set your custom normalizer for messages | |
|
|
398
457
|
|
|
399
458
|
## Creating Your Own Channel and Bus
|
|
400
|
-
|
|
459
|
+
|
|
460
|
+
This process allows you to define and integrate a custom **Channel** and **MessageBus** for your application, giving you
|
|
461
|
+
complete flexibility and control over how messages are processed, dispatched, and consumed. Each step provides the
|
|
462
|
+
necessary building blocks to create your own transport layer with full integration into the `MessagingModule`.
|
|
401
463
|
|
|
402
464
|
### 1. Create a `ChannelConfig`
|
|
403
|
-
|
|
465
|
+
|
|
466
|
+
A `ChannelConfig` class holds the configuration required to establish a stable connection to your service (e.g.,
|
|
467
|
+
RabbitMQ, Redis, etc.). Your class should implement the `ChannelConfig` interface and define necessary data like the
|
|
468
|
+
channel name and middlewares.
|
|
404
469
|
|
|
405
470
|
```typescript
|
|
406
471
|
export class YourChannelConfig implements ChannelConfig {
|
|
@@ -415,31 +480,40 @@ export class YourChannelConfig implements ChannelConfig {
|
|
|
415
480
|
```
|
|
416
481
|
|
|
417
482
|
### 2. Create a `Channel`
|
|
418
|
-
|
|
483
|
+
|
|
484
|
+
Next, create a class that implements the `Channel` interface. This class will serve as your `DataSource` and utilize the
|
|
485
|
+
configuration you defined in the `ChannelConfig` class.
|
|
419
486
|
|
|
420
487
|
```typescript
|
|
421
|
-
export class YourChannel extends Channel {
|
|
488
|
+
export class YourChannel extends Channel {
|
|
489
|
+
}
|
|
422
490
|
```
|
|
423
491
|
|
|
424
492
|
### 3. Create a `ChannelFactory`
|
|
425
|
-
|
|
493
|
+
|
|
494
|
+
A `ChannelFactory` is responsible for creating instances of your custom `Channel` class. It implements the
|
|
495
|
+
`IChannelFactory` interface and ensures proper injection into your app.
|
|
426
496
|
|
|
427
497
|
```typescript
|
|
498
|
+
|
|
428
499
|
@Injectable()
|
|
429
500
|
@ChannelFactory(YourChannel)
|
|
430
501
|
export class YourChannelFactory implements IChannelFactory<YourChannelConfig> {
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
502
|
+
create(channelConfig: YourChannelConfig): Channel {
|
|
503
|
+
return new YourChannel(channelConfig);
|
|
504
|
+
}
|
|
434
505
|
}
|
|
435
506
|
```
|
|
436
507
|
|
|
437
508
|
### 4. Create a `MessageBus`
|
|
438
|
-
|
|
509
|
+
|
|
510
|
+
The `MessageBus` handles the dispatching of messages in your system. Create a class implementing the `IMessageBus`
|
|
511
|
+
interface to send messages to your custom service (e.g., RabbitMQ, Redis, etc.).
|
|
439
512
|
|
|
440
513
|
```typescript
|
|
441
514
|
export class YourMessageBus implements IMessageBus {
|
|
442
|
-
constructor(private readonly yourChannel: YourChannel) {
|
|
515
|
+
constructor(private readonly yourChannel: YourChannel) {
|
|
516
|
+
}
|
|
443
517
|
|
|
444
518
|
async dispatch(message: RoutingMessage): Promise<MessageResponse | void> {
|
|
445
519
|
// Write your logic here to dispatch the message to your channel (e.g., RabbitMQ)
|
|
@@ -448,9 +522,12 @@ export class YourMessageBus implements IMessageBus {
|
|
|
448
522
|
```
|
|
449
523
|
|
|
450
524
|
### 5. Create a `MessageBusFactory`
|
|
451
|
-
|
|
525
|
+
|
|
526
|
+
The `MessageBusFactory` creates instances of your `MessageBus` and ensures it's properly integrated with your `Channel`.
|
|
527
|
+
It implements the `IMessageBusFactory` interface.
|
|
452
528
|
|
|
453
529
|
```typescript
|
|
530
|
+
|
|
454
531
|
@Injectable()
|
|
455
532
|
@MessageBusFactory(YourChannel)
|
|
456
533
|
export class YourMessageBusFactory implements IMessageBusFactory<YourChannel> {
|
|
@@ -461,9 +538,12 @@ export class YourMessageBusFactory implements IMessageBusFactory<YourChannel> {
|
|
|
461
538
|
```
|
|
462
539
|
|
|
463
540
|
### 6. Create a Consumer `MessageConsumer`
|
|
464
|
-
|
|
541
|
+
|
|
542
|
+
A consumer receives and processes messages. Create a class that implements the `IMessagingConsumer` interface and handle
|
|
543
|
+
the message processing within the `consume` method.
|
|
465
544
|
|
|
466
545
|
```typescript
|
|
546
|
+
|
|
467
547
|
@Injectable()
|
|
468
548
|
@MessageConsumer(YourChannel)
|
|
469
549
|
export class YourMessagingConsumer implements IMessagingConsumer<YourChannel> {
|
|
@@ -482,17 +562,20 @@ export class YourMessagingConsumer implements IMessagingConsumer<YourChannel> {
|
|
|
482
562
|
```
|
|
483
563
|
|
|
484
564
|
### 7. Add Custom `MessageOptions` to Your Bus (Optional)
|
|
565
|
+
|
|
485
566
|
You can create custom message options for your message.
|
|
486
567
|
|
|
487
568
|
```typescript
|
|
488
569
|
export class YourMessageOptions implements MessageOptions {
|
|
489
|
-
constructor(public readonly middlewares: Middleware[] = []) {
|
|
570
|
+
constructor(public readonly middlewares: Middleware[] = []) {
|
|
571
|
+
}
|
|
490
572
|
}
|
|
491
573
|
```
|
|
492
574
|
|
|
493
575
|
Classes with `Injectable()` decorator must be defined as providers in somewhere in application.
|
|
494
576
|
|
|
495
577
|
---
|
|
578
|
+
|
|
496
579
|
## Keywords
|
|
497
580
|
|
|
498
581
|
nestjs messaging library, nestjs message bus, nestjs service bus, <br>nestjs distributed systems,
|