본문 바로가기
NestJs/라이브러리

[NestJS] Redis 연동하기 - 2 (에러 해결 포함)

by Parkej 2022. 12. 7.

출처 및 참고


시작 전

cache-manager-redis-store라는 패키지를 이용해 redis를 연동시켜 보겠습니다.

 

사전 작업은 로컬에 레디스 설치입니다. (레디스 설치가 되어있다는 가정하)

 


시작

  • 전 글에는 내장 캐시 메모리를 사용하는 cache-manager 패키지만 다운로드하여 세팅을 하였습니다. 
  • redis를 연동하여 사용하려면 아래와 같은 패키지 다운이 필요합니다. 
$ npm i cache-manager-redis-store redis
$ npm i -D @types/cache-manager-redis-store

 

  • 설치가 잘 되었는지 확인해줍니다. package.json

app.module.ts
  • CacheModule의 코드를 추가로 작성합니다.
  • 공식문서에 따르면 ... CacheModule register에 인자를 넘겨주어야 합니다.
@Module({
  imports: [
    CacheModule.register<ClientOpts>({
      store: redisStore,

      // Store-specific configuration:
      host: 'localhost',
      port: 6379,
    }),
  ],
  controllers: [AppController],
})
export class AppModule {}

※ 로컬에서 구현한거라 host나 port의 값이 직접 작성되어 있지만 실제 production으로 올릴때는 env 같은 환경변수 파일을 사용하여 관리하여야 합니다.

 

하지만

  • 저어엉말 열이 받게도 원하지 않게 오류가 생깁니다. 심지어 ClientOpts를 임포트 안하고 register에 타입 제네릭을 지우면 오류는 다른곳에서 생깁니다. 
  • 저는 해당 문제를 해결하기위해 구글링을 한 결과 전 글에서 첨부했던 공식문서의 PR 코멘트를 확인할 수 있었습니다. 
  • https://github.com/dabroek/node-cache-manager-redis-store/issues/40

  • 아래와 같이 코드를 바꿔줍니다

  • 그리고 실행을 하면 역시나 오류가 납니다. 애플리케이션 생성조차 막힙니다. 

 

  • redis 패키지에 ClientOpts가 없다고 하니 지웠는데 그렇자니 타입에러가 나고 .... 혹시 모르니 버전을 낮춰봅니다. 
  • 2버전을 다운받습니다. 

$ npm i cache-manager-redis-store@2

 

  • 다행히 버전을 낮춘 것만으로 오류해결을 완료했습니다. 

 

  • 다시 url을 호출하면 성공적인 모습을 확인할 수 있습니다. 

 

여기서 요약하자면 

  • cache-manager 버전 4로 다운그레이
  • cache-manager-redis-store 버전 2로 다운그레이

를 하고 약간의 코드를 수정하면 정상작동을 확인할 수 있습니다 .

 

 

이제 레디스에 값을 임의로 생성하고 GET 요청을 통해 꺼내와보도록 합니다.

 

코드를 아래와같이 약간 수정하겠습니다. 

app.module.ts
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',
      port: 6379,
      ttl: 60,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
  • ttl은 데이터의 만료시간이라고 보시면 됩니다. 공식 문서에 따르면 시간 표기법은 second로 숫자가 1이면 1초가 됩니다.
  • ttl을 설정하지 않을 시 데이터의 만료시간은 5초입니다. (기본값)

레디스에 데이터 생성

레디스의 GUI 툴을 사용해서 간단하게 조작해도 되고 redis-cli 명령어를 통해 직접 입력하셔도 됩니다.

set d test

라는 쿼리를 통해 key가 "d"고 value가 "test"인 값을 생성했습니다.

 

GET API를 호출해봅시다. 

인솜니아에서도 콘솔에서도 값이 잘 출력되는것을 확인할 수 있습니다.


코드레벨로 레디스에 데이터 생성하기

레디스를 조작하기 위해 간단하게 get, set에 대한 코드를 작성합니다. 

  • get은 기존에 작성했던 코드가 있으므로 생략하고 set 부분만 작성했습니다. 

 

src/dtos/create-cache.dto.ts
  • class-validator 패키지를 먼저 다운받습니다.
$ npm i --save class-validator class-transformer
  • POST 요청 라우터 body에 담을 DTO를 만들어줍니다.
import { IsString } from "class-validator";

export class CreateCacheDto {
    @IsString()
    key: string;

    @IsString()
    value: string;
}
  • @IsString() 데코레이터를 사용해 DTO validation을 진행해줍니다. 만약 BODY에 대한 DTO를 만들고도 검증하는 구문이 없으면 아무리 값을 담아 요청해도 값이 담기지 않습니다. 그래서 꼭 class-validator의 데코레이터를 사용하도록 합시다. (다른 방법도 있겠지만 제일 기초적인 부분이라고 생각하면 될 것 같습니다.)

 

app.controller.ts
  • 아래와 같이 POST 요청에 대한 라우터를 작성합니다.
import { CreateCacheDto } from './dtos/create-cache.dto';
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
import { AppService } from './app.service';

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

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

  @Get('/cache/:key')
  async getCache(@Param('key') key: string) {
    try {
      return await this.appService.getCache(key);
    } catch (error) {
      throw error;
    }
  }
  // 추가
  @Post('/cache')
  async setCache(@Body() createCacheDto: CreateCacheDto) {
    try {
      await this.appService.setCache(createCacheDto);
      return {
        status: 'OK',
        data: createCacheDto
      }
    } catch (error) {
      throw error;
    }
  }
}

 

app.service.ts
import { CreateCacheDto } from './dtos/create-cache.dto';
import { CACHE_MANAGER, Inject, Injectable } from '@nestjs/common';
import { Cache } from 'cache-manager';

@Injectable()
export class AppService {
  
  constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}

  getHello(): string {
    return 'Hello World!';
  }

  async getCache(key: string) {
    try {
      const value = await this.cacheManager.get(key);
      console.log('getCache value : ', value);
      return value;
    } catch (error) {
      throw error;
    }
  }

  async setCache(createCacheDto: CreateCacheDto) {
    try {
      await this.cacheManager.set(createCacheDto.key, createCacheDto.value);
    } catch (error) {
      throw error;
    }
  }
}

 

테스트하기

  • POST 요청을 진행합니다.
  • BODY에는 DTO에 작성한 형태와 같이 적어줍니다. 

결과

API 툴 response
redis GUI 툴

POST로 데이터 생성 후 GET API 요청

로그

이렇게 잘 되는 것을 확인할 수 있습니다. 


NestJS를 가지고 cache 모듈을 이용하여 redis까지 연동시켜보았습니다. 

여러 방법은 존재하지만 공식문서를 기준으로 작성했음을 알립니다. 

 

다음에는 레디스를 활용하여 무언가를 만들어 볼까 합니다. 감사합니다.

 

다른 에러 사항이나 궁금점은 댓글로 남겨주세요

반응형

'NestJs > 라이브러리' 카테고리의 다른 글

[NestJS] Redis 연동하기 - 1  (0) 2022.12.07

댓글