Swapnil Gawali
Swapnil Gawali

Reputation: 73

How to reuse Redis connection inside Typeorm cache config in NestJs

I am using Redis to cache queries inside TypeOrm.

but the problem is, TypeOrm and Redis package is opening the separate connection, i just want to reuse the same connection for both.

this is typeorm config:

import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import { Constants } from '../utils/Constants';

export const typeOrmConfig: TypeOrmModuleOptions = {
    type: Constants.DB_TYPE,
    host: Constants.DB_HOST,
    port: Constants.DB_PORT,
    username: Constants.DB_USER_NAME,
    password: Constants.DB_PASSWORD,
    database: Constants.DB_NAME,
    entities: [ __dirname + '/../**/*.entity.{js,ts}' ],
    synchronize: true,
    logging: true,
    cache: {
        type: 'ioredis',
        duration: 60000,
        options: {
            host: 'localhost',
            password: 'swapnil',
            port: 6379
        }
    },
    extra: {
        max: 10,
        connectionTimeoutMillis: 2000
    }
};

i am using @svtslv/nestjs-ioredis package for redis:

import { Constants } from '../utils/Constants';

export const config = {
    host: Constants.REDIS_HOST,
    port: parseInt(Constants.REDIS_PORT),
    db: parseInt(Constants.REDIS_DB),
    password: Constants.REDIS_PASSWORD
};

and using this package, i am able to access redis inside my service class using:

public constructor(@InjectRedis() private readonly redis: Redis,) {}

Upvotes: 1

Views: 11929

Answers (1)

Daniel
Daniel

Reputation: 2531

After some digging in the TypeORM code base I came across two solutions (wiil one the other is a bit hacky and my case issues)

ORM CustomQueryResultCache

According to the doc, you can implement your own cache handler see: https://github.com/typeorm/typeorm/blob/master/docs/caching.md.

This is the better but harder solution due to the Interface that need to be implemented https://github.com/typeorm/typeorm/blob/master/src/cache/QueryResultCache.ts

In addition, you will need you register the TypeOrmModule with forRootAsync to first be able to connect to Redis.

Hacky fun times

According to the code base, you should be able to access the Redise client (connection) that TypeORM is creating.

On the type ORM connection there is a member called connection.queryResultCache for managing the cache. But furthermore there is a member name client on the queryResultCache (connection.queryResultCache.client)

See TypeORM redis Cache implamatation: https://github.com/typeorm/typeorm/blob/master/src/cache/RedisQueryResultCache.ts

import { Connection } from 'typeorm';

@Module({
  imports: [TypeOrmModule.forRoot()],
})
export class AppModule {
  constructor(private connection: Connection) {

    connection.queryResultCache.client // <-- Cache client.
  }
}

But it goes without saying that this is not the intended uses and this will couple your DB to Redis which is not that grate for future-proofing your codebase.

My honest opinion

According to the idea of separation of concerns I would recommend sticking with two connections instead of one just to keep the DB query Cache and the standard Cache separated.

This will allow you more flexibility in the future for integration testing and refactoring.

See: https://github.com/nestjs/typeorm/issues/59

Upvotes: 6

Related Questions