1.0.1 • Published 4 months ago

nestjs-redis-cache v1.0.1

Weekly downloads
-
License
MIT
Repository
-
Last release
4 months ago

NestJS Redis Cache

A simple and flexible Redis cache integration for NestJS applications.

Features

  • Easy integration with existing NestJS applications
  • Automatic caching of API responses
  • Customizable cache key generation
  • Flexible cache configuration via decorators
  • Support for asynchronous configuration

Installation

npm install nestjs-redis-cache

Quick Start

Register the module

import { Module } from '@nestjs/common';
import { RedisCacheModule } from 'nestjs-redis-cache';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    RedisCacheModule.register({
      client: {
        host: 'localhost',
        port: 6379,
      },
      ttl: 3600, // 1 hour in seconds
      keyPrefix: 'myapp_cache',
      isGlobal: true, // Register as global module
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Async configuration

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { RedisCacheModule } from 'nestjs-redis-cache';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    ConfigModule.forRoot(),
    RedisCacheModule.registerAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      isGlobal: true,
      useFactory: (configService: ConfigService) => ({
        client: {
          host: configService.get('REDIS_HOST'),
          port: configService.get('REDIS_PORT'),
          password: configService.get('REDIS_PASSWORD'),
        },
        ttl: configService.get('CACHE_TTL', 3600),
        keyPrefix: configService.get('CACHE_PREFIX', 'myapp_cache'),
      }),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Usage

Basic Usage

Once the module is registered, caching is automatically enabled for GET controller methods.

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

Customizing Cache Keys

You can customize how cache keys are generated using the @CacheKey decorator:

import { Controller, Get, Param, Query } from '@nestjs/common';
import { CacheKey, UseCache } from 'nestjs-redis-cache';
import { UserService } from './user.service';

@Controller('users')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Get(':id')
  @CacheKey({
    // Include only user ID in the cache key
    include: {
      params: ['id'],
      query: false,
      body: false,
    },
    ttl: 600, // 10 minutes
  })
  getUser(@Param('id') id: string) {
    return this.userService.findOne(id);
  }

  @Get()
  @CacheKey({
    // Include only specific query parameters in the cache key
    include: {
      query: ['page', 'limit', 'sort'],
    },
    ttl: 300, // 5 minutes
  })
  getUsers(@Query() query) {
    return this.userService.findAll(query);
  }

  @Get('profile')
  @UseCache(false) // Disable caching for this route
  getUserProfile() {
    return this.userService.getProfile();
  }
  
  @Get('dashboard')
  @AutoCache(1800) // Simple way to enable caching with a 30-minute TTL
  getDashboard() {
    return this.userService.getDashboard();
  }
}

Using the Cache Service

The package provides direct access to the cache service for manual caching:

import { Injectable } from '@nestjs/common';
import { RedisCacheService } from 'nestjs-redis-cache';

@Injectable()
export class UserService {
  constructor(private readonly cacheService: RedisCacheService) {}

  async findAll(filters: any) {
    // Using customKey for readable, user-friendly cache keys
    const cacheKey = this.cacheService.customKey('users', 'list', filters.status);
    
    // Try to get from cache
    const cachedUsers = await this.cacheService.get(cacheKey);
    if (cachedUsers) {
      return cachedUsers;
    }
    
    // Get from database if not in cache
    const users = await this.userRepository.findAll(filters);
    
    // Cache the result
    await this.cacheService.set(cacheKey, users, 300); // 5 minutes
    
    return users;
  }

  async findOne(id: string) {
    // Simple user-friendly key
    const cacheKey = this.cacheService.customKey('user', id);
    
    // Try to get from cache
    const cachedUser = await this.cacheService.get(cacheKey);
    if (cachedUser) {
      return cachedUser;
    }
    
    // Get from database if not in cache
    const user = await this.userRepository.findOne(id);
    
    // Cache the result
    await this.cacheService.set(cacheKey, user, 3600);
    
    return user;
  }

  async updateUser(id: string, data: any) {
    // Update user in database
    const user = await this.userRepository.update(id, data);
    
    // Delete user cache
    await this.cacheService.del(this.cacheService.customKey('user', id));
    
    // Delete any list caches that might include this user
    await this.cacheService.delByPrefix('users:list');
    
    return user;
  }
}

API Reference

RedisCacheModule

register(options: RedisCacheOptions)

Register the module with synchronous options.

registerAsync(options: RedisCacheAsyncOptions)

Register the module with asynchronous options.

RedisCacheService

get<T>(key: string): Promise<T | null>

Get a value from the cache.

set(key: string, value: any, ttl?: number): Promise<boolean>

Set a value in the cache.

del(key: string): Promise<boolean>

Delete a value from the cache.

delByPrefix(prefix: string): Promise<number>

Delete all values with a specific prefix.

clear(): Promise<boolean>

Clear all cache entries.

generateCacheKey(controllerName: string, methodName: string, request: Request, config?: CacheKeyConfig): string

Generate a cache key based on request and configuration.

generateKey(controllerName: string, methodName: string, id?: string | number): string

Generate a simple cache key based on controller and method names with optional ID.

customKey(...parts: any[]): string

Generate a user-friendly cache key. Can be used in several ways:

// Simple usage with parts
cacheService.customKey('users', 'list', 'active');  // 'users:list:active'

// With entity and ID
cacheService.customKey('user', userId);  // 'user:123'

// With named parameters for more structure
cacheService.customKey({ 
  entity: 'order', 
  action: 'details', 
  id: orderId,
  parts: [status, region]
});  // 'order:details:456:completed:north'

Decorators

@CacheKey(config: CacheKeyConfig)

Configure cache key generation for a controller method.

@UseCache(useCache: boolean = true)

Enable or disable caching for a controller method.

@AutoCache(ttl?: number, options?: Omit<CacheKeyConfig, 'ttl'>)

Simplified decorator that enables caching and configures the TTL in one step.

@CacheController(prefix?: string)

Controller decorator that adds support for automatic cache key generation.

License

MIT