Skip to content

Commit 0ca1895

Browse files
Init redis extension
0 parents  commit 0ca1895

21 files changed

+5646
-0
lines changed

.eslintrc.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
module.exports = {
2+
parser: '@typescript-eslint/parser',
3+
parserOptions: {
4+
project: 'tsconfig.json',
5+
tsconfigRootDir: __dirname,
6+
sourceType: 'module',
7+
},
8+
plugins: ['@typescript-eslint/eslint-plugin'],
9+
extends: [
10+
'plugin:@typescript-eslint/recommended',
11+
'plugin:prettier/recommended',
12+
],
13+
root: true,
14+
env: {
15+
node: true,
16+
jest: true,
17+
},
18+
ignorePatterns: ['.eslintrc.js'],
19+
rules: {
20+
'@typescript-eslint/interface-name-prefix': 'off',
21+
'@typescript-eslint/explicit-function-return-type': 'off',
22+
'@typescript-eslint/explicit-module-boundary-types': 'off',
23+
'@typescript-eslint/no-explicit-any': 'off',
24+
},
25+
};

.gitignore

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# compiled output
2+
/lib
3+
/dist
4+
/node_modules
5+
/build
6+
7+
# Logs
8+
logs
9+
*.log
10+
npm-debug.log*
11+
pnpm-debug.log*
12+
yarn-debug.log*
13+
yarn-error.log*
14+
lerna-debug.log*
15+
16+
# OS
17+
.DS_Store
18+
19+
# Tests
20+
/coverage
21+
/.nyc_output
22+
23+
# IDEs and editors
24+
/.idea
25+
.project
26+
.classpath
27+
.c9/
28+
*.launch
29+
.settings/
30+
*.sublime-workspace
31+
32+
# IDE - VSCode
33+
.vscode/*
34+
!.vscode/settings.json
35+
!.vscode/tasks.json
36+
!.vscode/launch.json
37+
!.vscode/extensions.json
38+
39+
# dotenv environment variable files
40+
.env
41+
.env.development.local
42+
.env.test.local
43+
.env.production.local
44+
.env.local
45+
46+
# temp directory
47+
.temp
48+
.tmp
49+
50+
# Runtime data
51+
pids
52+
*.pid
53+
*.seed
54+
*.pid.lock
55+
56+
# Diagnostic reports (https://nodejs.org/api/report.html)
57+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

.prettierrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"singleQuote": true,
3+
"trailingComma": "all"
4+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 nestjstools
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<p align="center">
2+
<image src="nestjstools-logo.png" width="400">
3+
</p>
4+
5+
# @nestjstools/messaging-redis-extension
6+
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+
9+
## Installation
10+
11+
```bash
12+
npm install @nestjstools/messaging @nestjstools/messaging-redis-extension
13+
```
14+
15+
or
16+
17+
```bash
18+
yarn add @nestjstools/messaging @nestjstools/messaging-redis-extension
19+
```
20+
## Redis Integration: Messaging Configuration Example
21+
22+
---
23+
24+
```typescript
25+
import {MessagingModule} from '@nestjstools/messaging';
26+
import {SendMessageHandler} from './handlers/send-message.handler';
27+
import {MessagerRedisExtensionModule, RedisChannelConfig} from "@nestjstools/messager-redis-extension";
28+
29+
@Module({
30+
imports: [
31+
MessagerRedisExtensionModule,
32+
MessagingModule.forRoot({
33+
buses: [
34+
{
35+
name: 'message.bus',
36+
channels: ['my-channel'],
37+
},
38+
{
39+
name: 'command.bus', //The naming is very flexible
40+
channels: ['redis-command'], //be sure if you defined same channels name as you defined below, you can bind multiple channels there, like send message to rabbitmq and redis at the same time
41+
},
42+
{
43+
name: 'event.bus',
44+
channels: ['redis-event'],
45+
},
46+
],
47+
channels: [
48+
new InMemoryChannelConfig({
49+
name: 'my-channel',
50+
middlewares: [],
51+
avoidErrorsForNotExistedHandlers: true,
52+
}),
53+
new RedisChannelConfig({
54+
name: 'redis-command',
55+
middlewares: [],
56+
avoidErrorsForNotExistedHandlers: false,
57+
queue: 'command-queue',
58+
connection: {
59+
port: 6379,
60+
host: '127.0.0.1',
61+
},
62+
}),
63+
new RedisChannelConfig({
64+
name: 'redis-event',
65+
middlewares: [],
66+
avoidErrorsForNotExistedHandlers: true,
67+
queue: 'event-queue',
68+
connection: {
69+
port: 6379,
70+
host: '127.0.0.1',
71+
},
72+
}),
73+
],
74+
debug: true,
75+
}),
76+
],
77+
})
78+
export class AppModule {
79+
}
80+
```
81+
82+
---
83+
84+
### Key Features:
85+
86+
1. **Multiple Message Buses**:
87+
- Configure distinct buses for **commands**, and **events**:
88+
- `command.bus` (command processing).
89+
- `event.bus` (event processing).
90+
91+
2. **In-Memory Channel**:
92+
- Simple and lightweight channel suitable for non-persistent messaging or testing purposes.
93+
94+
3. **Redis Channels**:
95+
- Fully integrated Redis configuration using `RedisChannelConfig`.
96+
97+
4. **Channel Details**:
98+
- `connection`: Specifies the Redis server connection.
99+
- `queue`: Specify a Redis queue name to consume messages from.
100+
101+
5. **Error Handling**:
102+
- Use `avoidErrorsForNotExistedHandlers` in `redis-event` to gracefully handle missing handlers for event messages.
103+
104+
6. **Debug Mode**:
105+
- Enable `debug: true` to assist in monitoring and troubleshooting messages.
106+
107+
This configuration provides a solid foundation for integrating redis as part of your messaging system. It facilitates the decoupling of commands, events, and in-memory operations, ensuring reliable and scalable communication across distributed systems.
108+
109+
---
110+
111+
## Configuration options
112+
113+
### RedisChannel
114+
115+
#### **RedisChannelConfig**
116+
117+
| **Property** | **Description** | **Default Value** |
118+
|----------------------------------------|----------------------------------------------------------------------|-------------------|
119+
| **`name`** | Name of the Redis channel (e.g., `'redis-command'`). | |
120+
| **`connection`** | URI for the Redis connection`. | |
121+
| **`queue`** | The Redis queue to consume messages from (e.g., `'my_app.command'`). | |
122+
| **`enableConsumer`** | Enables or disables the consumer for this channel. | `true` |
123+
| **`avoidErrorsForNotExistedHandlers`** | Avoid errors if no handler is available for the message. | `false` |
124+
125+
---
126+
127+
## Real world working example with RabbitMQ & Redis
128+
https://github.com/nestjstools/messaging-rabbitmq-example

nest-cli.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"$schema": "https://json.schemastore.org/nest-cli",
3+
"collection": "@nestjs/schematics",
4+
"sourceRoot": "src",
5+
"compilerOptions": {
6+
"deleteOutDir": true
7+
}
8+
}

nestjstools-logo.png

40.1 KB
Loading

package.json

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
{
2+
"name": "messaging-redis-extension",
3+
"version": "1.0.0",
4+
"description": "Extension to handle messages and dispatch them over Redis",
5+
"author": "Sebastian Iwanczyszyn",
6+
"private": false,
7+
"license": "MIT",
8+
"main": "lib/index.js",
9+
"publishConfig": {
10+
"access": "public"
11+
},
12+
"bugs": {
13+
"url": "https://github.com/nestjstools/messaging-reids-extension/issues"
14+
},
15+
"repository": {
16+
"type": "git",
17+
"url": "git+https://github.com/nestjstools/messaging-redis-extension"
18+
},
19+
"keywords": [
20+
"nestjs-tools",
21+
"nestjs",
22+
"distributed",
23+
"messaging",
24+
"nestjs-messaging",
25+
"message-bus",
26+
"service-bus",
27+
"microservices",
28+
"redis",
29+
"nestjs redis"
30+
],
31+
"files": [
32+
"lib",
33+
"LICENSE",
34+
"package.json"
35+
],
36+
"scripts": {
37+
"build": "nest build",
38+
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
39+
"start": "nest start",
40+
"start:dev": "nest start --watch",
41+
"start:debug": "nest start --debug --watch",
42+
"start:prod": "node dist/main",
43+
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
44+
"test": "jest",
45+
"test:watch": "jest --watch",
46+
"test:cov": "jest --coverage",
47+
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
48+
"test:e2e": "jest --config ./test/jest-e2e.json"
49+
},
50+
"dependencies": {
51+
"bullmq": "^5.41.3"
52+
},
53+
"peerDependencies": {
54+
"@nestjstools/messaging": "^2.X",
55+
"@nestjs/common": "^10.x||^11.x",
56+
"@nestjs/core": "^10.x||^11.x",
57+
"reflect-metadata": "^0.2.0",
58+
"rxjs": "^7.x"
59+
},
60+
"devDependencies": {
61+
"@nestjs/cli": "^10.0.0",
62+
"@nestjs/schematics": "^10.0.0",
63+
"@nestjs/testing": "^10.0.0",
64+
"@nestjstools/messaging": "^2.3.0",
65+
"@types/express": "^5.0.0",
66+
"@types/jest": "^29.5.2",
67+
"@types/node": "^20.3.1",
68+
"@types/supertest": "^6.0.0",
69+
"@typescript-eslint/eslint-plugin": "^8.0.0",
70+
"@typescript-eslint/parser": "^8.0.0",
71+
"eslint": "^8.0.0",
72+
"eslint-config-prettier": "^9.0.0",
73+
"eslint-plugin-prettier": "^5.0.0",
74+
"jest": "^29.5.0",
75+
"prettier": "^3.0.0",
76+
"source-map-support": "^0.5.21",
77+
"supertest": "^7.0.0",
78+
"ts-jest": "^29.1.0",
79+
"ts-loader": "^9.4.3",
80+
"ts-node": "^10.9.1",
81+
"tsconfig-paths": "^4.2.0",
82+
"typescript": "^5.1.3"
83+
},
84+
"jest": {
85+
"moduleFileExtensions": [
86+
"js",
87+
"json",
88+
"ts"
89+
],
90+
"rootDir": "src",
91+
"testRegex": ".*\\.spec\\.ts$",
92+
"transform": {
93+
"^.+\\.(t|j)s$": "ts-jest"
94+
},
95+
"collectCoverageFrom": [
96+
"**/*.(t|j)s"
97+
],
98+
"coverageDirectory": "../coverage",
99+
"testEnvironment": "node"
100+
}
101+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { ChannelConfig } from '@nestjstools/messaging';
2+
3+
export class RedisChannelConfig extends ChannelConfig {
4+
public readonly connection: Connection;
5+
public readonly queue: string;
6+
7+
constructor({
8+
name,
9+
connection,
10+
queue,
11+
enableConsumer,
12+
avoidErrorsForNotExistedHandlers,
13+
middlewares,
14+
normalizer,
15+
}: RedisChannelConfig) {
16+
super(name, avoidErrorsForNotExistedHandlers, middlewares, enableConsumer, normalizer)
17+
this.connection = connection;
18+
this.queue = queue;
19+
}
20+
}
21+
22+
interface Connection {
23+
host: string;
24+
port: number;
25+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { RedisChannel } from './redis.channel';
2+
import {Injectable} from "@nestjs/common";
3+
import { ChannelFactory, IChannelFactory } from '@nestjstools/messaging';
4+
import { RedisChannelConfig } from './redis.channel-config';
5+
6+
@Injectable()
7+
@ChannelFactory(RedisChannelConfig)
8+
export class RedisChannelFactory implements IChannelFactory<RedisChannelConfig> {
9+
create(channelConfig: RedisChannelConfig): RedisChannel {
10+
return new RedisChannel(channelConfig);
11+
}
12+
}

0 commit comments

Comments
 (0)