Skip to content

인터셉터

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')으로 InternalAxiosRequestConfigmetadata?: { 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 한 곳에서 수행합니다. 여러 파일에서 분산 등록하지 않습니다.

TIENIPIA QUALIFIED STANDARD