Interceptors
14.2.1. Request Interceptors
- Request interceptors are executed before all API requests are sent to the server.
- The authentication token must be automatically injected into the
Authorizationheader within the request interceptor. - Token injection logic must be separated and managed in
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. Response Interceptors
- Response interceptors are executed before the server response is delivered to the component.
- Error responses must be transformed into a standardized format within the interceptor.
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: 'Please check your network connection.',
code: 'NETWORK_ERROR',
})
}
const { status, data } = error.response
return Promise.reject({
status,
message: data?.message ?? 'An unknown error occurred.',
code: data?.code ?? 'UNKNOWN_ERROR',
})
}14.2.3. Logging Interceptors
- In development environments, request and response information must be logged to the console.
- In production environments, the logging interceptor must not be registered.
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
}- The
config.metadatatype must be declared by adding ametadata?: { startTime: number }property toInternalAxiosRequestConfigvia module augmentation (declare module 'axios'). - Conditional registration must use
import.meta.env.DEV.
14.2.4. Interceptor Registration Order
- Request interceptors execute in LIFO (Last In, First Out) order. Response interceptors execute in FIFO (First In, First Out) order. Since the order affects logic execution, interceptors must be registered in the intended sequence.
| Category | Execution Order | Recommended Registration Order |
|---|---|---|
| Request interceptors | LIFO (Last In, First Out) | Logging -> Auth token injection |
| Response interceptors | FIFO (First In, First Out) | Error transformation -> Logging |
typescript
// src/api/client.ts (final registration order)
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)
}- Interceptor files must be separated by functionality under the
src/api/interceptors/directory. - Interceptor registration must be performed in a single location:
src/api/client.ts. Interceptors must not be registered across multiple files.