Improving NestJS Speed with Redis Caching Solutions
Boost Your NestJS App Using Redis Cache
Caching is a powerful technique to speed up your applications, making them more responsive and efficient. In this post, I'll walk you through how to integrate Redis cache into a NestJS application. Redis is an in-memory data structure store that can be used as a database, cache, and message broker. By the end of this tutorial, you'll have a solid understanding of how to set up and use Redis in your NestJS projects.
Why Use Redis?
Redis offers several benefits for caching:
Speed: Since Redis is an in-memory store, it's incredibly fast.
Persistence: It supports data persistence, allowing you to save snapshots of your data to disk.
Data Structures: Redis supports various data structures such as strings, hashes, lists, sets, and more.
Scalability: Redis can be scaled easily to handle large amounts of data and high request rates.
Setting Up Redis
Before we dive into the code, make sure you have Redis installed and running. You can either download Redis from its official website or use a Docker container for a quick setup:
docker run --name redis -p 6379:6379 -d redis
Setting Up NestJS
If you don't already have a NestJS project, let's create a new one:
nest new redis-cache-example
cd redis-cache-example
Installing Dependencies
Next, we'll need to install some packages for Redis and caching:
npm install cache-manager cache-manager-redis-store redis
Integrating Redis with NestJS
1. Configure Cache Module
First, we need to configure the CacheModule in our app.module.ts
file to use Redis:
import { Module, CacheModule } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import * as redisStore from 'cache-manager-redis-store';
@Module({
imports: [
CacheModule.register({
store: redisStore,
host: 'localhost', // Redis server host
port: 6379, // Redis server port
ttl: 600, // Time to live (seconds)
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Here, we configure the CacheModule to use Redis as our cache store, specifying the host and port where Redis is running. We also set a time-to-live (TTL) of 600 seconds for cached data.
2. Using Cache in Services
Now, let's use the cache in our service. We'll inject the cache manager and use it to cache data. Here's an example in app.service.ts
:
import { Injectable, Inject } from '@nestjs/common';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';
@Injectable()
export class AppService {
constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}
async getHello(): Promise<string> {
const cacheKey = 'hello_cache';
let cachedData = await this.cacheManager.get<string>(cacheKey);
if (!cachedData) {
cachedData = 'Hello World!';
await this.cacheManager.set(cacheKey, cachedData, { ttl: 600 }); // Cache for 10 minutes
}
return cachedData;
}
}
In this service, we first try to get the cached data using cacheManager.get
. If there's no cached data, we set it using cacheManager.set
.
3. Handling Cache in Controllers
Next, we use this service method in our controller. Here’s how our app.controller.ts
looks:
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
async getHello(): Promise<string> {
return this.appService.getHello();
}
}
This controller simply calls the getHello
method from our service to return the cached or newly set data.
Advanced Caching Techniques
Caching Method Results
NestJS provides a @Cacheable
decorator to cache method results effortlessly. Here’s how you can use it:
import { Injectable } from '@nestjs/common';
import { Cacheable } from 'nestjs-cacheable';
@Injectable()
export class AppService {
@Cacheable({ ttl: 600 }) // Cache for 10 minutes
async getHello(): Promise<string> {
return 'Hello World!';
}
}
With the @Cacheable
decorator, the method result is automatically cached, saving you from manually handling cache logic.
Invalidating Cache
Sometimes, you might need to invalidate the cache when the underlying data changes. Use cacheManager.del
to remove cached data. Here’s an example:
import { Injectable, Inject, CACHE_MANAGER } from '@nestjs/common';
import { Cache } from 'cache-manager';
@Injectable()
export class AppService {
constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}
async updateHello(newData: string): Promise<void> {
const cacheKey = 'hello_cache';
await this.cacheManager.del(cacheKey);
// Update the data in your database or other persistent storage
}
}
In this example, when updateHello
is called, the cache for hello_cache
is invalidated, ensuring that subsequent requests fetch the latest data.
Conclusion
Happy coding!