Caching
Caching
μΊμ±μ μ±μ μ±λ₯μ ν₯μμν€λ λ° λμμ΄λλ νλ₯νκ³ κ°λ¨ν κΈ°μ μ λλ€. κ³ μ±λ₯ λ°μ΄ν° μ‘μΈμ€λ₯Ό μ 곡νλ μμ λ°μ΄ν° μ μ₯μ μν μν©λλ€.
Installation
λ¨Όμ  νμν ν¨ν€μ§λ₯Ό μ€μΉνμμμ€.
$ npm install --save cache-managerIn-memory cache
Nestλ λ€μν μΊμ μ€ν λ¦¬μ§ μ κ³΅μλ₯Ό μν ν΅ν© APIλ₯Ό μ κ³΅ν©λλ€. λ΄μ₯λ κ²μ μΈ λ©λͺ¨λ¦¬ λ°μ΄ν° μ μ₯μμ
λλ€. κ·Έλ¬λ Redisμ κ°μ λ³΄λ€ ν¬κ΄μ μΈ μ루μ
μΌλ‘ μ½κ² μ νν  μ μμ΅λλ€. μΊμ±μ νμ±ννλ €λ©΄ λ¨Όμ  CacheModuleμ κ°μ Έ μμ register() λ©μλλ₯Ό νΈμΆνμμμ€.
import { CacheModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';
@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
})
export class ApplicationModule {}κ·Έλ° λ€μ λ°μ΄ν°λ₯Ό μΊμν  μμΉμ CacheInterceptorλ₯Ό μ°κ²°νμμμ€.
@Controller()
@UseInterceptors(CacheInterceptor)
export class AppController {
  @Get()
  findAll(): string[] {
    return [];
  }
}warning κ²½κ³
GETμλ ν¬μΈνΈλ§ μΊμλ©λλ€. λν μμ μλ΅ μ€λΈμ νΈ (@Res())λ₯Ό μ£Όμ νλ HTTP μλ² λΌμ°νΈλ μΊμ μΈν°μ ν°λ₯Ό μ¬μ©ν μ μμ΅λλ€. μμΈν λ΄μ©μ μλ΅ λ§€νμ μ°Έμ‘°νμμμ€.
Global cache
νμν μμ©κ΅¬μ μμ μ€μ΄λ €λ©΄ CacheInterceptorλ₯Ό μ μμΌλ‘ λͺ¨λ  μλ ν¬μΈνΈμ λ°μΈλ© ν  μ μμ΅λλ€.
import { CacheModule, Module, CacheInterceptor } from '@nestjs/common';
import { AppController } from './app.controller';
import { APP_INTERCEPTOR } from '@nestjs/core';
@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: CacheInterceptor,
    },
  ],
})
export class ApplicationModule {}WebSockets & Microservices
MicroServiceμ ν¨ν΄λΏλ§ μλλΌ WebSocket κ°μ
μμκ² CacheInterceptorλ₯Ό μ μ©ν  μλ μμ΅λλ€ (μ¬μ©μ€μΈ μ μ‘ λ°©λ²μ κ΄κ³μμ΄).
@@filename()
@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client: Client, data: string[]): Observable<string[]> {
  return [];
}
@@switch
@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client, data) {
  return [];
}info ννΈ
@CacheKey()λ°μ½λ μ΄ν°λ@nestjs/commonν¨ν€μ§μμ κ°μ Έμ΅λλ€.
κ·Έλ¬λ μΊμλ λ°μ΄ν°λ₯Ό μ μ₯νκ³  κ²μνλ λ° μ¬μ©λλ ν€λ₯Ό μ§μ νλ €λ©΄ μΆκ°@CacheKey()λ°μ½λ μ΄ν°κ° νμν©λλ€. λν λͺ¨λ  κ²μ μΊμνμ§ μμμΌν©λλ€. λ¨μν λ°μ΄ν°λ₯Ό 쿼리νμ§ μκ³  μΌλΆ λΉμ¦λμ€ μμ
μ μννλ μμ
μ μΊμλμ§ μμμΌ ν©λλ€.
Customize caching
μΊμλ λͺ¨λ  λ°μ΄ν°μλ μ체 TTL (λ§λ£ μκ°)μ΄ μμ΅λλ€. κΈ°λ³Έκ°μ μ¬μ©μ μ μνλ €λ©΄ options κ°μ²΄λ₯Ό register()λ©μλμ μ λ¬νμμμ€.
CacheModule.register({
  ttl: 5, // seconds
  max: 10, // maximum number of items in cache
});Different stores
μ΄ μλΉμ€λ νλμμ cache-managerλ₯Ό νμ©ν©λλ€. cache-manager ν¨ν€μ§λ Redisμ κ°μ λ€μν μ μ©ν μ μ₯μλ₯Ό μ§μν©λλ€. μ§μλλ μ μ²΄ μ μ₯μ λͺ©λ‘μ μ¬κΈ°μμ νμΈν  μ μμ΅λλ€. Redis μ€ν μ΄λ₯Ό μ€μ νλ €λ©΄ ν΄λΉ μ΅μ
κ³Ό ν¨κ» ν¨ν€μ§λ₯Ό register()λ©μλμ μ λ¬νλ©΄ λ©λλ€.
import * as redisStore from 'cache-manager-redis-store';
import { CacheModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';
@Module({
  imports: [
    CacheModule.register({
      store: redisStore,
      host: 'localhost',
      port: 6379,
    }),
  ],
  controllers: [AppController],
})
export class ApplicationModule {}Adjust tracking
κΈ°λ³Έμ μΌλ‘ Nestλ μμ² URL (HTTP μ±) λλ μΊμ ν€ (μΉ μμΌ λ° λ§μ΄ν¬λ‘ μλΉμ€ μ±, @CacheKey()λ°μ½λ μ΄ν°λ₯Ό ν΅ν΄ μ€μ )λ₯Ό μ¬μ©νμ¬ μΊμ λ μ½λλ₯Ό μλ ν¬μΈνΈμ μ°κ²°ν©λλ€. κ·ΈλΌμλ λΆκ΅¬νκ³  λλ‘λ HTTP ν€λ (μ: profile μλ ν¬μΈνΈλ₯Ό μ¬λ°λ₯΄κ² μλ³νκΈ°μν Authorization)λ₯Ό μ¬μ©νλ λ± λ€μν μμλ₯Ό κΈ°λ°μΌλ‘ μΆμ μ μ€μ νκ³ μ ν  μ μμ΅λλ€.
μ΄λ₯Ό μν΄ CacheInterceptorμ μλΈ ν΄λμ€λ₯Ό μμ±νκ³  trackBy()λ©μλλ₯Ό λ체νμμμ€.
@Injectable()
class HttpCacheInterceptor extends CacheInterceptor {
  trackBy(context: ExecutionContext): string | undefined {
    return 'key';
  }
}Async configuration
μ»΄νμΌμ μ μ μΌλ‘ μ λ¬νλ λμ  λͺ¨λ μ΅μ
μ λΉλκΈ°μ μΌλ‘ μ λ¬ν  μ μμ΅λλ€. μ΄ κ²½μ° λΉλκΈ° ꡬμ±μ μ²λ¦¬νλ λͺ κ°μ§ λ°©λ²μ μ κ³΅νλ registerAsync() λ©μλλ₯Ό μ¬μ©νμμμ€.
ν κ°μ§ λ°©λ²μ ν©ν 리 κΈ°λ₯μ μ¬μ©νλ κ²μ λλ€.
CacheModule.registerAsync({
  useFactory: () => ({
    ttl: 5,
  }),
});Our factory behaves like all other asynchronous module factories (it can be async and is able to inject dependencies through inject).
CacheModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    ttl: configService.getString('CACHE_TTL'),
  }),
  inject: [ConfigService],
});Alternatively, you can use the useClass method:
CacheModule.registerAsync({
  useClass: CacheConfigService,
});μμ ꡬμ±μ CacheModuleλ΄μμ CacheConfigServiceλ₯Ό μΈμ€ν΄μ€ννμ¬ μ΅μ
 κ°μ²΄λ₯Ό μ»λ λ° μ¬μ©ν©λλ€. CacheConfigServiceλ μ€μ  μ΅μ
μ μ κ³΅νκΈ° μν΄ CacheOptionsFactory μΈν°νμ΄μ€λ₯Ό ꡬνν΄μΌ ν©λλ€:
@Injectable()
class CacheConfigService implements CacheOptionsFactory {
  createCacheOptions(): CacheModuleOptions {
    return {
      ttl: 5,
    };
  }
}λ€λ₯Έ λͺ¨λμμ κ°μ Έμ¨ κΈ°μ‘΄ κ΅¬μ± κ³΅κΈμλ₯Ό μ¬μ©νλ €λ©΄ useExisting ꡬ문μ μ¬μ©νμμμ€.
CacheModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});μ΄κ²μ useClassμ λμΌνκ² μλνλ©° ν κ°μ§ μ€μν μ°¨μ΄μ μ΄ μμ΅λλ€. CacheModuleμ κ°μ Έμ¨ λͺ¨λμ μ°Ύμμ μ체μ μΌλ‘ μΈμ€ν΄μ€ν νλ λμ  μ΄λ―Έ μμ±λ ConfigServiceλ₯Ό μ¬μ¬μ©ν©λλ€.
Last updated
Was this helpful?