Search code examples
herokucachingredisnestjs

How can I pass REDIS_URI for NestJS cache manager?


In the official documentation this is the correct way to use the cache manager with Redis:

import * as redisStore from 'cache-manager-redis-store';
import { CacheModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';

@Module({
  imports: [
    CacheModule.register({
      store: redisStore,
      host: 'localhost',
      port: 6379,
    }),
  ],
  controllers: [AppController],
})
export class AppModule {}

Source: https://docs.nestjs.com/techniques/caching#different-stores

However, I did not find any documentation on how to pass Redis instance data using REDIS_URI. I need to use it with Heroku and I believe this is a common use case.


Solution

  • EDIT:

    now they are type-safe: https://github.com/nestjs/nest/pull/8592


    I've exploring a bit about how the redis client is instantiated. Due to this line I think that the options that you've passed to CacheModule.register will be forwarded to Redis#createClient (from redis package). Therefore, you can pass the URI like:

    CacheModule.register({
      store: redisStore,
      url: 'redis://localhost:6379'
    })
    

    try this and let me know if it works.


    edit:

    Explaining how I got that:

    Taking { store: redisStore, url: '...' } as options.

    1. Here in CacheModule.register I found that your options will live under CACHE_MODULE_OPTIONS token (as a Nest provider)
    2. Then I search for places in where this token will be used. Then I found here that those options were passed to cacheManager.caching. Where cacheManager is the module cache-manager
    3. Looking into to the cacheManager.caching's code here, you'll see that your options is now their args parameter
    4. Since options.store (redisStore) is the module exported by cache-manager-redis-store package, args.store.create method is the same function as in redisStore.create
    5. Thus args.store.create(args) is the same as doing redisStore.create(options) which, in the end, will call Redis.createClient passing this options