To read more articles like this, visit my blog
Today we will talk about Redis. A very powerful and easy database to use. It is very popular for caching.
Prerequisites
Basic Understanding of Caching
Experience in NestJS
The problem
We at our company are building a property management solution where we have to maintain many users and they can have various permissions based on their role.
So after each successful login client makes a request to get the user profile details along with the permissions for them. As the query is very complex and requires the joining of multiple tables it took a long time to load.
And the users have to wait a long time before seeing anything on their screen which is a very bad user experience.
The Solution
So after digging through some possible solutions, we found that Caching is the answer for us. Because of 2 reasons mainly
This API is called very frequently.
Users' permissions don’t change so frequently
So after some digging, it was clear that Redis might be the best way to go for us. And Redis is a good choice for caching
So Why Redis?
Redis is really really fast. It was written in C so it’s really efficient.
It’s very easy to use. It’s almost like our browser's local storage but way more powerful. You just set some data with a key and get it back with that same key.
All the major languages/frameworks have support for Redis.
It’s really popular and used by many major companies so stability is not an issue at all
NestJS makes it really easy to use Redis. Now we will see how to use it.
Step 1. Install dependencies
Install the following dependencies
yarn add cache-manager cache-manager-redis-store
Step 2. Add Caching Module
Then create a module for caching
nest g module redis-cache
Then add the following code to your redis-cache.module.ts
file
import { CacheModule, Module } from '@nestjs/common';
import { RedisCacheService } from './redis-cache.service';
import { ConfigModule, ConfigService } from '@nestjs/config';
import * as redisStore from 'cache-manager-redis-store';
@Module({
imports: [
CacheModule.*registerAsync*({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => ({
store: redisStore,
host: configService.get('REDIS_HOST'),
port: configService.get('REDIS_PORT'),
ttl: configService.get('CACHE_TTL'),
max: configService.get('MAX_ITEM_IN_CACHE')
})
})
],
providers: [RedisCacheService],
exports: [RedisCacheService]
})
export class RedisCacheModule {}
A few things to note here…
REDIS_HOST
: It specifies the host of our Redis database (ex: localhost)
REDIS_PORT
: The default port value is 6479
CACHE_TTL
: It specifies the amount of time in seconds before a value is invalidated
MAX_ITEM_IN_CACHE
: It specifies the maximum number of items that should be kept in the cache.
Step 3. Create a Service
Create a new service for caching
nest g service redis-cache
Then add the following code in redis-cache.service.ts
file
import { ***CACHE_MANAGER***, Inject, Injectable } from '@nestjs/common';
import { Cache } from 'cache-manager';
@Injectable()
export class SomeService {
constructor(@Inject(***CACHE_MANAGER***) private readonly cache: Cache) {}
async get(key): Promise<any> {
return await this.cache.get(key);
}
async set(key, value) {
await this.cache.set(key, value, 1000);
}
async reset() {
await this.cache.reset();
}
async del(key) {
await this.cache.del(key);
}
}
These are utility functions to work with Cache.
Step 4. Use Caching Service
Inside any service, you can now import the RedisCacheModule into a different module.
@Module({
imports: [RedisCacheModule],
controllers: [UserController],
providers: [UserService],
exports: [UserService]
})
export class SomeModule {}
Then use it in any service inside that module
@Injectable()
export class UserService {
constructor(private cacheManager: RedisCacheService) {}
async setSomeValue(KEY , value){
await this.cacheManager.set(KEY , value);
}
async getSomeValue(KEY){
await this.cacheManager.get(KEY);
}
}
Bonus: Dockerize the whole application
If you run your application now you will run into an error because you don’t have the Redis database up and running. You have two choice
Install and run Redis on your local machine
Use docker to pull the Redis image from the docker hub.
We will see how to do the later now.
The main Dockerfile is typical for any nodeJS application
FROM node:12-alpine
WORKDIR /app
ADD package.json /app/package.json
RUN yarn install
ADD . /app
EXPOSE 3000
CMD ["yarn", "start"]
We have to add another and the docker-compose.yml file
version: '3'
services:
redis:
image: 'redis:alpine'
node-app:
build: .
ports:
- "3000:3000"
Here we are pulling the official Redis image from the docker hub and run it so that our application can access it.
If you run Redis from the docker image you have to change the
REDIS_HOST
value(used in step 2) toredis
(used in docker-compose file)
Now you should be more comfortable about using Redis in your next project. It’s really a very useful tool to keep under your developer's belt.
That’s it for today. Happy Coding! :D
Get in touch with me via LinkedIn or my Personal Website.