-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
캐시모듈 적용 문제 참고
1. 캐시 모듈 적용 문제
NestJS 공식 문서를 따라 캐시 모듈을 적용하려고 했으나, 버전 문제로 인해 문제가 발생했습니다.
cache-manager 라이브러리의 버전 5는 NestJS에서 제대로 지원되지 않았습니다.
아래는 버전 5를 NestJS에서 적용하는 방법을 다시 정리한 코드입니다.
CacheModule.registerAsync({
isGlobal: true,
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
store: (await redisStore({
url: configService.get('REDIS_URL') || 'redis://localhost:6379/',
})) as unknown as CacheStore,
}),
inject: [ConfigService],
}), 2. 캐시 서비스 사용 방법 문제
또한, Redis에 데이터를 저장할 때 TTL(Time To Live) 설정 문제도 발생했습니다.
처음에 TTL을 직접 설정했을 때 실제로는 TTL이 적용되지 않는 문제가 있었으며, TTL을 초 단위로 설정해야 했습니다.
await this.cache.set(key, sorted_emergency_center_list, ttl ); // ttl is ms
await this.cache.set(key, sorted_emergency_center_list, { ttl: 60 } as any);nestjs 공식문서를 토대로 작성한 첫번째 코드는 ttl이 정상작동 하지 않았습니다.
두 번째 코드와 같이 객체옵션을 사용해야 ttl이 정상 작동합니다.
3. nestia(typia)와 redis문제
또 다른 문제는 Redis에서 데이터를 JSON 형식으로 저장하고, cache-manager에서 데이터를 파싱할 때 발생했습니다. 이로 인해 Date 타입 데이터가 문자열로 변환되어 nestia에서 검증할 때 문제가 발생했습니다. 이 문제를 해결하기 위해 마지막 반환 타입을 변경해야 했습니다. 아래와 같은 타입을 적용하여 문제를 해결했습니다.
export type DateToString<T> = {
[K in keyof T]: T[K] extends Date
? string | Date
: T[K] extends object
? DateToString<T[K]>
: T[K] extends (infer U)[]
? DateToString<U>[]
: T[K];
};
```ts
export namespace ErEmergencyCenterResponse {
export type GetEmergencyCenterList = DateToString<ErEmergencyCenter.GetEmergencyCenterListQueryReturn>;
}
class service{
async getDepartmentStatusList(
@CurrentUser() user: ErAuth.AccessTokenSignPayload,
): Promise<Try<ErDepartmentResponse.GetDepartmentStatusListDto>> {
const DepartmentStatusList = await this.erDepartmentService.getDepartmentStatusList({ user });
return createResponse(DepartmentStatusList);
}
}이러한 타입 변환을 통해 nestia와 Redis의 Date 문제를 해결했습니다. 그러나 사용성에 문제가 있어서 추가적인 해결 방법을 고민 중입니다.
또한, 마지막으로 타입을 변경하려는 시도에서 발생하는 에러에 대한 해결 방법을 찾아야 합니다.
export type DateToString<T> = {
[K in keyof T]: T[K] extends Date
? string | Date
: T[K] extends object
? DateToString<T[K]>
: T[K] extends (infer U)[]
? DateToString<U>[]
: T[K];
};
export interface ResponseDTO<T> {
/**
* @type T
* @description 요청에 대한 응답
*/
result: T;
/**
* @type true
* @description 요청이 성공했는지 여부
*/
is_success: true;
/**
* @type number
* @description 요청부터 응답까지 걸린 시간
*/
request_to_response?: number;
/**
* @type string
* @description 요청에 대한 메시지
*/
message: string;
}
export type Try<T> = ResponseDTO<T>;
export type TryCatch<T, E extends ERROR<string, ErrorHttpStatusCode>> = E extends any ? ResponseDTO<T> : ResponseDTO<T>;
export namespace ErEmergencyCenterResponse {
export type GetEmergencyCenterList = DateToString<ErEmergencyCenter.GetEmergencyCenterListQueryReturn>;
}
class service {
async getEmergencyCenterList(
@TypedQuery()
query: ErEmergencyCenterRequest.GetEmergencyCenterListQuery,
): Promise<Try<ErEmergencyCenterResponse.GetEmergencyCenterList>> {
const result = await this.erEmergencyCenterService.getEmergencyCenterListByQuery(query);
return createResponse(result);
}
}YJ-AnthonyJo
Metadata
Metadata
Assignees
Labels
No labels