Skip to content

Commit

Permalink
feat: add cluster support and foo samples
Browse files Browse the repository at this point in the history
  • Loading branch information
juandav committed Dec 22, 2023
1 parent 2da034e commit ad220d7
Show file tree
Hide file tree
Showing 56 changed files with 34,394 additions and 20 deletions.
84 changes: 77 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ yarn add @nestjs-modules/ioredis ioredis

#### RedisModule.forRoot(options, connection?)

##### Single Type (forRoot)

```ts
import { Module } from '@nestjs/common';
import { RedisModule } from '@nestjs-modules/ioredis';
Expand All @@ -38,9 +40,41 @@ import { AppController } from './app.controller';
@Module({
imports: [
RedisModule.forRoot({
config: {
url: 'redis://localhost:6379',
},
type: 'single',
url: 'redis://localhost:6379',
}),
],
controllers: [AppController],
})
export class AppModule {}
```

##### Cluster Type (forRoot)

```ts
import { Module } from '@nestjs/common';
import { RedisModule } from '@nestjs-modules/ioredis';
import { AppController } from './app.controller';

@Module({
imports: [
RedisModule.forRoot({
type: 'cluster',
nodes: [
{
host: '127.0.0.1',
port: 6379
},
{
host: '127.0.0.2',
port: 6379
}
],
options: {
redisOptions: {
password: '123456'
}
}
}),
],
controllers: [AppController],
Expand All @@ -50,6 +84,8 @@ export class AppModule {}

#### RedisModule.forRootAsync(options, connection?)

##### Single Type (forRootAsync)

```ts
import { Module } from '@nestjs/common';
import { RedisModule } from '@nestjs-modules/ioredis';
Expand All @@ -59,9 +95,43 @@ import { AppController } from './app.controller';
imports: [
RedisModule.forRootAsync({
useFactory: () => ({
config: {
url: 'redis://localhost:6379',
},
type: 'single',
url: 'redis://localhost:6379',
}),
}),
],
controllers: [AppController],
})
export class AppModule {}
```

##### Cluster Type (forRootAsync)

```ts
import { Module } from '@nestjs/common';
import { RedisModule } from '@nestjs-modules/ioredis';
import { AppController } from './app.controller';

@Module({
imports: [
RedisModule.forRootAsync({
useFactory: () => ({
type: 'cluster',
nodes: [
{
host: '127.0.0.1',
port: 6379
},
{
host: '127.0.0.2',
port: 6379
}
],
options: {
redisOptions: {
password: '123456'
}
}
}),
}),
],
Expand All @@ -73,9 +143,9 @@ export class AppModule {}
#### InjectRedis(connection?)

```ts
import Redis from 'ioredis';
import { Controller, Get } from '@nestjs/common';
import { InjectRedis } from '@nestjs-modules/ioredis';
import Redis from 'ioredis';

@Controller()
export class AppController {
Expand Down
16 changes: 13 additions & 3 deletions lib/redis.interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import { ModuleMetadata, Type } from '@nestjs/common/interfaces';
import { RedisOptions } from 'ioredis';
import { RedisOptions, ClusterOptions, ClusterNode } from 'ioredis';

export interface RedisModuleOptions {
config: RedisOptions & { url?: string };
export interface RedisSingleOptions {
type: 'single';
url?: string;
options?: RedisOptions;
}

export interface RedisClusterOptions {
type: 'cluster';
nodes: ClusterNode[];
options?: ClusterOptions;
}

export type RedisModuleOptions = RedisSingleOptions | RedisClusterOptions;

export interface RedisModuleOptionsFactory {
createRedisModuleOptions(): Promise<RedisModuleOptions> | RedisModuleOptions;
}
Expand Down
12 changes: 8 additions & 4 deletions lib/redis.module.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Injectable } from '@nestjs/common';
import Redis from 'ioredis';

import { Injectable } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { RedisModule } from './redis.module';
import { getRedisConnectionToken } from './redis.utils';
Expand All @@ -9,7 +10,8 @@ describe('RedisModule', () => {
it('Instance Redis', async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [RedisModule.forRoot({
config: {
type: 'single',
options: {
host: '127.0.0.1',
port: 6379,
password: '123456',
Expand All @@ -28,7 +30,8 @@ describe('RedisModule', () => {
it('Instance Redis client provider', async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [RedisModule.forRoot({
config: {
type: 'single',
options: {
name: '1',
host: '127.0.0.1',
port: 6379,
Expand Down Expand Up @@ -61,7 +64,8 @@ describe('RedisModule', () => {

const module: TestingModule = await Test.createTestingModule({
imports: [RedisModule.forRoot({
config: {
type: 'single',
options: {
host: '127.0.0.1',
port: 6379,
password: '123456',
Expand Down
18 changes: 12 additions & 6 deletions lib/redis.utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { RedisModuleOptions } from './redis.interfaces';
import Redis from 'ioredis';
import { RedisModuleOptions, RedisOptions } from './redis.interfaces';
import {
REDIS_MODULE_CONNECTION,
REDIS_MODULE_CONNECTION_TOKEN,
Expand All @@ -15,10 +15,16 @@ export function getRedisConnectionToken(connection?: string): string {
}

export function createRedisConnection(options: RedisModuleOptions) {
const { config } = options;
if (config.url) {
return new Redis(config.url, config);
} else {
return new Redis(config);
const { type, options: commonOptions } = options;

switch (type) {
case 'cluster':
return new Redis.Cluster(options.nodes, commonOptions);
case 'single':
const { url, port, host } = options;
const connectionOptions: RedisOptions = { ...commonOptions, url, port, host };
return new Redis(connectionOptions);
default:
throw new Error('Invalid configuration');
}
}
34 changes: 34 additions & 0 deletions sample/cluster/01-forRoot/e2e/cats/cats.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import * as request from 'supertest';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { CoreModule } from '../../src/core/core.module';

describe('Cats', () => {
const catsService = { findAll: () => ['test'] };

let app: INestApplication;

beforeAll(async () => {
const moduleRef = await Test.createTestingModule({
imports: [CatsModule, CoreModule],
})
.overrideProvider(CatsService)
.useValue(catsService)
.compile();

app = moduleRef.createNestApplication();
await app.init();
});

it(`/GET cats`, () => {
return request(app.getHttpServer()).get('/cats').expect(200).expect({
data: catsService.findAll(),
});
});

afterAll(async () => {
await app.close();
});
});
14 changes: 14 additions & 0 deletions sample/cluster/01-forRoot/e2e/jest-e2e.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"json"
],
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
"testRegex": "/e2e/.*\\.(e2e-test|e2e-spec).(ts|tsx|js)$",
"collectCoverageFrom" : ["src/**/*.{js,jsx,tsx,ts}", "!**/node_modules/**", "!**/vendor/**"],
"coverageReporters": ["json", "lcov"]
}
14 changes: 14 additions & 0 deletions sample/cluster/01-forRoot/jest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"json"
],
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
"testRegex": "/src/.*\\.(test|spec).(ts|tsx|js)$",
"collectCoverageFrom" : ["src/**/*.{js,jsx,tsx,ts}", "!**/node_modules/**", "!**/vendor/**"],
"coverageReporters": ["json", "lcov"]
}
Loading

0 comments on commit ad220d7

Please sign in to comment.