kakasoo

NestJS에서의 Redis 적용 본문

프로그래밍/NestJS

NestJS에서의 Redis 적용

카카수(kakasoo) 2023. 5. 9. 10:36
반응형

내가 적용한 시점에는 일일 다운로드 3만 건이었고, 현재는 5만건인 라이브러리다.

서비스에서도 사용하고 있는데 사용성이 무척 좋아서 공유한다.

Installation

# with npm
npm install @liaoliaots/nestjs-redis ioredis
# with yarn
yarn add @liaoliaots/nestjs-redis ioredis
# with pnpm
pnpm add @liaoliaots/nestjs-redis ioredis

npm: @liaoliaots/nestjs-redis

라이브러리는 @liaoliaots/nestjs-redis 와 **ioredis 이렇게 두 개를 설치해야 하고,

노드 버전은 12.22 이상, NestJS는 9.0.0 이상, ioredis는 5.0.0 이상이어야 한다.

처음 적용하는 시점에서는 NestJS 버전이 걸릴 수도 있으니 미리 업데이트를 해두도록 하자.

 

app.module.ts

import { Module } from '@nestjs/common';
import { RedisModule } from '@liaoliaots/nestjs-redis';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [
    RedisModule.forRoot({
      readyLog: true,
      config: {
        host: 'localhost',
        port: 6380,
        password: 'bitnami'
      }
    }),
    CatsModule
  ]
})
export class AppModule {}

nestjs-redis 라이브러리는 모듈 형태로 Redis를 사용할 수 있게 해준다.

 

RedisModule.forRoot(options, isGlobal)

export interface RedisModuleOptions {
    /**
     * If set to `true`, all clients will be closed automatically on nestjs application shutdown.
     *
     * @defaultValue `true`
     */
    closeClient?: boolean;
    /**
     * Common options to be passed to each client.
     */
    commonOptions?: RedisOptions;
    /**
     * If set to `true`, then ready logging will be displayed when the client is ready.
     *
     * @defaultValue `false`
     */
    readyLog?: boolean;
    /**
     * If set to `true`, then errors that occurred while connecting will be displayed by the built-in logger.
     *
     * @defaultValue `true`
     */
    errorLog?: boolean;
    /**
     * Used to specify single or multiple clients.
     */
    config?: RedisClientOptions | RedisClientOptions[];
}

내부에 받는 프로퍼티는 이렇다.

Redis를 세팅하기 위해 필요한 설정들을 모두 받을 수 있고, 옵션과 전역 설정이 가능하게 isGlobal이 있다.

두 프로퍼티는 모두 옵셔널한 값들이기 때문에 host, port, password 등만 잘 설정해주면 모두 완료된다

 

cats.service.ts

import { Injectable } from '@nestjs/common';
import { InjectRedis } from '@liaoliaots/nestjs-redis';
import Redis from 'ioredis';
import { Cat } from './cat';
import { CreateCatDto } from './create-cat.dto';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [new Cat(1, 'Test Cat 1', 'Test Breed 1'), new Cat(2, 'Test Cat 2', 'Test Breed 2')];

  constructor(@InjectRedis() private readonly client: Redis) {}

  async findAll(): Promise<Cat[]> {
    const cats = await this.client.get('cats');
    if (cats) return JSON.parse(cats) as Cat[];

    await this.client.set('cats', JSON.stringify(this.cats), 'EX', 120);
    return this.cats;
  }

  async create(cat: CreateCatDto): Promise<Cat> {
    await this.client.del('cats');

    const newCat = { id: this.cats[this.cats.length - 1].id + 1, ...cat };
    this.cats.push(newCat);
    return newCat;
  }
}

이렇게 주입해놓은 상태라면, 모듈 어디에서나 해당 라이브러리를 이용해 Redis에 접근이 가능하다.

 

import { Injectable } from '@nestjs/common';
import { InjectRedis } from '@liaoliaots/nestjs-redis';
import Redis from 'ioredis';

@Injectable()
export class CatsService {
  constructor(@InjectRedis() private readonly client: Redis) {}
}

InjectRedis 데코레이터를 이용해서 client를 감싸주기만 하면 Redis 타입의 객체가 주입된다.

 

const cache = await this.cacheManager.get(cacheKey);
if (cache) {
  return JSON.parse(cache);
}

key를 이용해 데이터에 접근할 수도 있고,

 

await this.cacheManager.set(cacheKey, JSON.stringify(response), 'EX', 30);

key에 데이터를 저장해둘 수도 있다.

기본적인 사용 방식은 NestJS에 내장 되어 있는 cache-manager랑 비슷한 형태기 때문에 사용이 용이하다.

반응형