인터셉터
14.2.1. 요청 인터셉터
- 요청 인터셉터는 모든 API 요청이 서버로 전송되기 전에 실행됩니다.
- 인증 토큰은 요청 인터셉터에서
Authorization헤더에 자동 주입합니다. - 토큰 주입 로직은
src/api/interceptors/auth.ts에 분리하여 관리합니다.
typescript
// src/api/interceptors/auth.ts
import type { InternalAxiosRequestConfig } from 'axios'
import { useAuthStore } from '@/stores/useAuthStore'
export function attachAuthToken(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig {
const authStore = useAuthStore()
const token = authStore.accessToken
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
}14.2.2. 응답 인터셉터
- 응답 인터셉터는 서버 응답을 컴포넌트에 전달하기 전에 실행됩니다.
- 에러 응답은 인터셉터에서 표준 형식으로 변환합니다.
typescript
// src/api/interceptors/error.ts
import type { AxiosError } from 'axios'
import type { ApiError } from '@/types/api'
export function handleResponseError(error: AxiosError<ApiError>): Promise<never> {
if (!error.response) {
return Promise.reject({
status: 0,
message: '네트워크 연결을 확인해 주십시오.',
code: 'NETWORK_ERROR',
})
}
const { status, data } = error.response
return Promise.reject({
status,
message: data?.message ?? '알 수 없는 오류가 발생했습니다.',
code: data?.code ?? 'UNKNOWN_ERROR',
})
}14.2.3. 로깅 인터셉터
- 개발 환경에서는 요청 및 응답 정보를 콘솔에 출력합니다.
- 프로덕션 환경에서는 로깅 인터셉터를 등록하지 않습니다.
typescript
// src/api/interceptors/logger.ts
import type { InternalAxiosRequestConfig, AxiosResponse } from 'axios'
export function logRequest(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig {
config.metadata = { startTime: Date.now() }
console.log(`[API Request] ${config.method?.toUpperCase()} ${config.url}`)
return config
}
export function logResponse(response: AxiosResponse): AxiosResponse {
const duration = Date.now() - (response.config.metadata?.startTime ?? 0)
console.log(`[API Response] ${response.config.url} → ${response.status} (${duration}ms)`)
return response
}config.metadata타입은 모듈 확장(declare module 'axios')으로InternalAxiosRequestConfig에metadata?: { startTime: number }속성을 추가하여 선언합니다.- 조건부 등록은
import.meta.env.DEV를 사용합니다.
14.2.4. 인터셉터 구성 순서
- 요청 인터셉터는 나중에 등록된 것이 먼저 실행됩니다 (LIFO). 응답 인터셉터는 먼저 등록된 것이 먼저 실행됩니다 (FIFO). 순서가 로직에 영향을 미치므로 반드시 의도한 순서대로 등록해야 합니다.
| 구분 | 실행 순서 | 권장 등록 순서 |
|---|---|---|
| 요청 인터셉터 | LIFO (후입선출) | 로깅 → 인증 토큰 주입 |
| 응답 인터셉터 | FIFO (선입선출) | 에러 변환 → 로깅 |
typescript
// src/api/client.ts (최종 등록 순서)
if (import.meta.env.DEV) {
apiClient.interceptors.request.use(logRequest)
}
apiClient.interceptors.request.use(attachAuthToken)
apiClient.interceptors.response.use((res) => res, handleResponseError)
if (import.meta.env.DEV) {
apiClient.interceptors.response.use(logResponse)
}- 인터셉터 파일은
src/api/interceptors/디렉토리에 기능별로 분리합니다. - 인터셉터 등록은
src/api/client.ts한 곳에서 수행합니다. 여러 파일에서 분산 등록하지 않습니다.