refactor. LRU 캐시를 사용하여 API 응답 데이터 캐싱 로직 개선

This commit is contained in:
clkim
2026-03-30 13:05:57 +09:00
parent d5e783113d
commit 8f98bdbd3a
2 changed files with 44 additions and 14 deletions

View File

@@ -1,3 +1,4 @@
import { LRUCache } from 'lru-cache'
import { usePageDataStore } from '#layers/stores/usePageDataStore'
import { useLoadingStore } from '#layers/stores/useLoadingStore'
import { commonFetch } from '#layers/utils/apiUtil'
@@ -5,6 +6,12 @@ import { getGameDomain, getPathAfterLanguage } from '#layers/utils/urlUtil'
import { DEFAULT_LOCALE_CODE } from '@/i18n.config'
import type { PageDataResponse } from '#layers/types/api/pageData'
/** 페이지 데이터 API 응답 LRU */
const pageDataResponseCache = new LRUCache<string, PageDataResponse>({
max: 100,
ttl: 1000 * 60,
})
export default defineNuxtRouteMiddleware(async (to, _from) => {
const runtimeConfig = useRuntimeConfig()
@@ -64,9 +71,18 @@ export default defineNuxtRouteMiddleware(async (to, _from) => {
}
}
pageDataResponse = (await commonFetch('GET', apiUrl, {
query: queryParams,
})) as PageDataResponse | null
const cacheKey = `${apiUrl}:${JSON.stringify(queryParams)}`
const cached = pageDataResponseCache.get(cacheKey)
if (cached) {
pageDataResponse = cached
} else {
pageDataResponse = (await commonFetch('GET', apiUrl, {
query: queryParams,
})) as PageDataResponse | null
if (pageDataResponse?.code === 0 && 'value' in pageDataResponse) {
pageDataResponseCache.set(cacheKey, pageDataResponse)
}
}
console.log('🚀 ~ pageData.global response:', pageDataResponse)
} catch (error) {
@@ -119,7 +135,7 @@ export default defineNuxtRouteMiddleware(async (to, _from) => {
})
)
}
return navigateTo(`/${currentLangCode}/home`)
return navigateTo(`/${currentLangCode}/home`, { external: true })
}
// [TODO]

View File

@@ -61,11 +61,16 @@ function setCacheHeaders(
event.node.res.setHeader('Cache-Control', cacheControl)
}
const cache = new LRUCache<string, WebInspectionData>({
const inspectionDataCache = new LRUCache<string, WebInspectionData>({
max: 100, // 캐시에 저장할 최대 항목 수
ttl: 1000 * 30, // 30초 동안 캐시 유지
})
const gameDataResponseCache = new LRUCache<string, GameDataResponse>({
max: 100,
ttl: 1000 * 60, // 60초
})
/**
* Locale Middleware 역할 함수
* URL의 언어 코드를 최종 언어로 변경하거나 추가
@@ -152,14 +157,23 @@ export default defineEventHandler(async event => {
game_domain: gameDomain || '',
lang_code: getPathLocale(event?.node.req.url),
}
const response = await $fetch<GameDataResponse>(gameApiUrl, {
query: queryParams,
})
const gameDataCacheKey = `${gameApiUrl}:${JSON.stringify(queryParams)}`
const cachedGameData = gameDataResponseCache.get(gameDataCacheKey)
if (cachedGameData) {
gameDataResponse = cachedGameData
} else {
const response = await $fetch<GameDataResponse>(gameApiUrl, {
query: queryParams,
})
gameDataResponse = response
if (gameDataResponse?.code === 0 && 'value' in gameDataResponse) {
gameDataResponseCache.set(gameDataCacheKey, gameDataResponse)
}
}
gameDataResponse = response
gameDataLangCodes = response?.value?.lang_codes || null
gameDataDefaultLangCode = response?.value?.default_lang_code || null
gameDataIntro = response?.value?.intro?.page_url || ''
gameDataLangCodes = gameDataResponse?.value?.lang_codes || null
gameDataDefaultLangCode = gameDataResponse?.value?.default_lang_code || null
gameDataIntro = gameDataResponse?.value?.intro?.page_url || ''
event.context.gameDomain = gameDomain
} catch (error) {
// eslint-disable-next-line no-console
@@ -201,7 +215,7 @@ export default defineEventHandler(async event => {
let inspectionData
// 3. 캐시된 데이터가 없거나 만료되었을 때만 API 호출
const cachedData = cache.get(cacheKey)
const cachedData = inspectionDataCache.get(cacheKey)
if (cachedData) {
inspectionData = cachedData
} else {
@@ -214,7 +228,7 @@ export default defineEventHandler(async event => {
})
inspectionData = response?.value?.inspection as WebInspectionData
if (inspectionData) {
cache.set(cacheKey, inspectionData) // 캐시에 저장
inspectionDataCache.set(cacheKey, inspectionData) // 캐시에 저장
}
}