@nestjstools/messaging-amazon-sqs-extension 1.2.0 → 1.3.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 +18 -16
- package/lib/channel/amazon-sqs.channel-config.d.ts +2 -1
- package/lib/channel/amazon-sqs.channel-config.js +3 -1
- package/lib/channel/amazon-sqs.channel-config.js.map +1 -1
- package/lib/consumer/amazon-sqs-messaging.consumer.d.ts +1 -0
- package/lib/consumer/amazon-sqs-messaging.consumer.js +24 -0
- package/lib/consumer/amazon-sqs-messaging.consumer.js.map +1 -1
- package/lib/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<image src="nestjstools-logo.png" width="400">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
# @nestjstools/messaging-amazon-sqs
|
|
5
|
+
# @nestjstools/messaging-amazon-sqs-extension
|
|
6
6
|
|
|
7
7
|
A NestJS library for managing asynchronous and synchronous messages with support for buses, handlers, channels, and consumers. This library simplifies building scalable and decoupled applications by facilitating robust message handling pipelines while ensuring flexibility and reliability.
|
|
8
8
|
|
|
@@ -32,11 +32,11 @@ yarn add @nestjstools/messaging @nestjstools/messaging-amazon-sqs-extension
|
|
|
32
32
|
import { Module } from '@nestjs/common';
|
|
33
33
|
import { MessagingModule } from '@nestjstools/messaging';
|
|
34
34
|
import { SendMessageHandler } from './handlers/send-message.handler';
|
|
35
|
-
import {
|
|
35
|
+
import { AmazonSqsChannelConfig, MessagingAmazonSqsExtensionModule } from '@nestjstools/messaging-amazon-sqs-extension';
|
|
36
36
|
|
|
37
37
|
@Module({
|
|
38
38
|
imports: [
|
|
39
|
-
|
|
39
|
+
MessagingAmazonSqsExtensionModule, // Importing the SQS extension module
|
|
40
40
|
MessagingModule.forRoot({
|
|
41
41
|
buses: [
|
|
42
42
|
{
|
|
@@ -57,7 +57,8 @@ import { MessagerAmazonSQSExtensionModule, AmazonSQSChannelConfig } from "@nestj
|
|
|
57
57
|
},
|
|
58
58
|
maxNumberOfMessages: 3, // optional
|
|
59
59
|
visibilityTimeout: 10, // optional
|
|
60
|
-
waitTimeSeconds: 5, // Every 5 seconds consumer will pull 3 messages from queue - optional
|
|
60
|
+
waitTimeSeconds: 5, // Every 5 seconds consumer will pull 3 messages from queue - optional,
|
|
61
|
+
deadLetterQueue: false,
|
|
61
62
|
}),
|
|
62
63
|
],
|
|
63
64
|
debug: true, // Optional: Enable debugging for Messaging operations
|
|
@@ -81,7 +82,7 @@ export class AppController {
|
|
|
81
82
|
) {}
|
|
82
83
|
|
|
83
84
|
@Get('/sqs')
|
|
84
|
-
|
|
85
|
+
createUser(): string {
|
|
85
86
|
this.sqsMessageBus.dispatch(new RoutingMessage(new CreateUser('John FROM SQS'), 'my_app_command.create_user'));
|
|
86
87
|
|
|
87
88
|
return 'Message sent';
|
|
@@ -177,17 +178,18 @@ this.sqsMessageBus.dispatch(
|
|
|
177
178
|
### AmazonSqsChannel
|
|
178
179
|
|
|
179
180
|
#### **AmazonSqsChannelConfig**
|
|
180
|
-
| **Property** | **Description**
|
|
181
|
-
|
|
182
|
-
| **`name`** | The name of the Amazon SQS channel (e.g., `'sqs-event'`).
|
|
183
|
-
| **`region`** | The AWS region for the SQS queue (e.g., `'us-east-1'`).
|
|
184
|
-
| **`queueUrl`** | The URL of the SQS queue (e.g., `'http://localhost:9324/queue/test_queue'`).
|
|
185
|
-
| **`credentials`** | AWS credentials for SQS (optional).
|
|
186
|
-
| **`enableConsumer`** | Whether to enable message consumption (i.e., processing received messages).
|
|
187
|
-
| **`autoCreate`** | Automatically create the queue if it doesn’t exist.
|
|
188
|
-
| **`maxNumberOfMessages`** | The maximum number of messages to retrieve from the queue in one request.
|
|
189
|
-
| **`visibilityTimeout`** | The time in seconds that the message will remain invisible to other consumers after being fetched.
|
|
190
|
-
| **`waitTimeSeconds`** | The amount of time (in seconds) for long polling. The consumer will wait up to this time for messages.
|
|
181
|
+
| **Property** | **Description** | **Default Value** |
|
|
182
|
+
|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------|-------------------|
|
|
183
|
+
| **`name`** | The name of the Amazon SQS channel (e.g., `'sqs-event'`). | |
|
|
184
|
+
| **`region`** | The AWS region for the SQS queue (e.g., `'us-east-1'`). | |
|
|
185
|
+
| **`queueUrl`** | The URL of the SQS queue (e.g., `'http://localhost:9324/queue/test_queue'`). | |
|
|
186
|
+
| **`credentials`** | AWS credentials for SQS (optional). | |
|
|
187
|
+
| **`enableConsumer`** | Whether to enable message consumption (i.e., processing received messages). | `true` |
|
|
188
|
+
| **`autoCreate`** | Automatically create the queue if it doesn’t exist. | `true` |
|
|
189
|
+
| **`maxNumberOfMessages`** | The maximum number of messages to retrieve from the queue in one request. | 1 |
|
|
190
|
+
| **`visibilityTimeout`** | The time in seconds that the message will remain invisible to other consumers after being fetched. | 20 |
|
|
191
|
+
| **`waitTimeSeconds`** | The amount of time (in seconds) for long polling. The consumer will wait up to this time for messages. | 10 |
|
|
192
|
+
| **`deadLetterQueue`** | When set to `true`, a dead-letter queue (DLQ) is automatically created. The DLQ name follows the pattern: `<queue_name>_dead_letter`. | `false` |
|
|
191
193
|
---
|
|
192
194
|
|
|
193
195
|
## Real world working example with RabbitMQ & Redis - but might be helpful to understand how it works
|
|
@@ -9,7 +9,8 @@ export declare class AmazonSqsChannelConfig extends ChannelConfig {
|
|
|
9
9
|
readonly visibilityTimeout?: number;
|
|
10
10
|
readonly waitTimeSeconds?: number;
|
|
11
11
|
readonly autoCreate?: boolean;
|
|
12
|
-
|
|
12
|
+
readonly deadLetterQueue?: boolean;
|
|
13
|
+
constructor({ name, credentials, queueUrl, maxNumberOfMessages, visibilityTimeout, waitTimeSeconds, region, autoCreate, deadLetterQueue, enableConsumer, avoidErrorsForNotExistedHandlers, middlewares, normalizer, }: AmazonSqsChannelConfig);
|
|
13
14
|
}
|
|
14
15
|
interface Credentials {
|
|
15
16
|
accessKeyId: string;
|
|
@@ -12,7 +12,8 @@ class AmazonSqsChannelConfig extends messaging_1.ChannelConfig {
|
|
|
12
12
|
visibilityTimeout;
|
|
13
13
|
waitTimeSeconds;
|
|
14
14
|
autoCreate;
|
|
15
|
-
|
|
15
|
+
deadLetterQueue;
|
|
16
|
+
constructor({ name, credentials, queueUrl, maxNumberOfMessages, visibilityTimeout, waitTimeSeconds, region, autoCreate, deadLetterQueue, enableConsumer, avoidErrorsForNotExistedHandlers, middlewares, normalizer, }) {
|
|
16
17
|
super(name, avoidErrorsForNotExistedHandlers, middlewares, enableConsumer, normalizer);
|
|
17
18
|
let url;
|
|
18
19
|
try {
|
|
@@ -30,6 +31,7 @@ class AmazonSqsChannelConfig extends messaging_1.ChannelConfig {
|
|
|
30
31
|
this.visibilityTimeout = visibilityTimeout ?? 20;
|
|
31
32
|
this.waitTimeSeconds = waitTimeSeconds ?? 10;
|
|
32
33
|
this.autoCreate = autoCreate ?? false;
|
|
34
|
+
this.deadLetterQueue = deadLetterQueue ?? false;
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
exports.AmazonSqsChannelConfig = AmazonSqsChannelConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"amazon-sqs.channel-config.js","sourceRoot":"","sources":["../../src/channel/amazon-sqs.channel-config.ts"],"names":[],"mappings":";;;AAAA,sDAAuD;AAEvD,MAAa,sBAAuB,SAAQ,yBAAa;IACvC,WAAW,CAAe;IAC1B,QAAQ,CAAS;IACjB,SAAS,CAAU;IACnB,QAAQ,CAAU;IAClB,MAAM,CAAS;IACf,mBAAmB,CAAU;IAC7B,iBAAiB,CAAU;IAC3B,eAAe,CAAU;IACzB,UAAU,CAAW;
|
|
1
|
+
{"version":3,"file":"amazon-sqs.channel-config.js","sourceRoot":"","sources":["../../src/channel/amazon-sqs.channel-config.ts"],"names":[],"mappings":";;;AAAA,sDAAuD;AAEvD,MAAa,sBAAuB,SAAQ,yBAAa;IACvC,WAAW,CAAe;IAC1B,QAAQ,CAAS;IACjB,SAAS,CAAU;IACnB,QAAQ,CAAU;IAClB,MAAM,CAAS;IACf,mBAAmB,CAAU;IAC7B,iBAAiB,CAAU;IAC3B,eAAe,CAAU;IACzB,UAAU,CAAW;IACrB,eAAe,CAAW;IAE1C,YAAY,EACE,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,MAAM,EACN,UAAU,EACV,eAAe,EACf,cAAc,EACd,gCAAgC,EAChC,WAAW,EACX,UAAU,GACa;QACnC,KAAK,CAAC,IAAI,EAAE,gCAAgC,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;QACvF,IAAI,GAAG,CAAC;QACR,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,GAAG,CAAC,CAAA;QACpD,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAC/C,IAAI,CAAC,QAAQ,GAAG,GAAG,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC;QAC/C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,IAAI,CAAC,CAAC;QACpD,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,IAAI,EAAE,CAAC;QACjD,IAAI,CAAC,eAAe,GAAG,eAAe,IAAI,EAAE,CAAC;QAC7C,IAAI,CAAC,UAAU,GAAG,UAAU,IAAI,KAAK,CAAC;QACtC,IAAI,CAAC,eAAe,GAAG,eAAe,IAAI,KAAK,CAAC;IAClD,CAAC;CACF;AA9CD,wDA8CC"}
|
|
@@ -7,5 +7,6 @@ export declare class AmazonSqsMessagingConsumer implements IMessagingConsumer<Am
|
|
|
7
7
|
private channel?;
|
|
8
8
|
consume(dispatcher: ConsumerMessageDispatcher, channel: AmazonSqsChannel): Promise<void>;
|
|
9
9
|
onError(errored: ConsumerDispatchedMessageError, channel: AmazonSqsChannel): Promise<void>;
|
|
10
|
+
private createDeadLetterQueue;
|
|
10
11
|
onApplicationShutdown(signal?: string): Promise<any>;
|
|
11
12
|
}
|
|
@@ -44,10 +44,34 @@ let AmazonSqsMessagingConsumer = class AmazonSqsMessagingConsumer {
|
|
|
44
44
|
await delay(channel.config.waitTimeSeconds);
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
+
await this.createDeadLetterQueue(channel);
|
|
47
48
|
processPollMessages();
|
|
48
49
|
return Promise.resolve();
|
|
49
50
|
}
|
|
50
51
|
async onError(errored, channel) {
|
|
52
|
+
if (!channel.config.deadLetterQueue) {
|
|
53
|
+
return Promise.resolve();
|
|
54
|
+
}
|
|
55
|
+
const command = new client_sqs_1.SendMessageCommand({
|
|
56
|
+
QueueUrl: `${channel.config.queueUrl}_dead_letter`,
|
|
57
|
+
MessageBody: JSON.stringify(errored.dispatchedConsumerMessage.message),
|
|
58
|
+
MessageAttributes: {
|
|
59
|
+
messagingRoutingKey: {
|
|
60
|
+
DataType: "String",
|
|
61
|
+
StringValue: errored.dispatchedConsumerMessage.routingKey,
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
await channel.client.send(command);
|
|
66
|
+
return Promise.resolve();
|
|
67
|
+
}
|
|
68
|
+
createDeadLetterQueue(channel) {
|
|
69
|
+
if (!channel.config.deadLetterQueue) {
|
|
70
|
+
return Promise.resolve();
|
|
71
|
+
}
|
|
72
|
+
channel.client.send(new client_sqs_1.CreateQueueCommand({
|
|
73
|
+
QueueName: `${channel.config.queueName}_dead_letter`,
|
|
74
|
+
}));
|
|
51
75
|
return Promise.resolve();
|
|
52
76
|
}
|
|
53
77
|
async onApplicationShutdown(signal) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"amazon-sqs-messaging.consumer.js","sourceRoot":"","sources":["../../src/consumer/amazon-sqs-messaging.consumer.ts"],"names":[],"mappings":";;;;;;;;;AAAA,sEAAiE;AACjE,sDAA6E;AAE7E,2CAAmE;AACnE,sDAAyD;AAEzD,
|
|
1
|
+
{"version":3,"file":"amazon-sqs-messaging.consumer.js","sourceRoot":"","sources":["../../src/consumer/amazon-sqs-messaging.consumer.ts"],"names":[],"mappings":"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"}
|