/** * API 호출을 위한 편의 함수 * * @template T - 응답 데이터의 타입 * @param path - API 엔드포인트 경로 (예: '/users', '/users/1') * @param options - 요청 및 에러 처리 옵션 * @returns Promise - API 응답 데이터 * * @example * // GET 요청 (기본 - 전역 로딩 자동 적용) * const users = await useApi('/users') * * // POST 요청 (커스텀 로딩 메시지) * const newUser = await useApi('/users', { * method: 'POST', * body: { name: 'John', email: 'john@example.com' }, * loadingMessage: '사용자를 생성하는 중...' * }) * * // 전역 로딩 없이 API 호출 * const data = await useApi('/users', { * useGlobalLoading: false * }) * * // 에러를 직접 처리 * try { * const data = await useApi('/users', { handleError: false }) * } catch (error) { * // 직접 에러 처리 * } * * // FormData 업로드 * const formData = new FormData() * formData.append('file', file) * await useApi('/upload', { * method: 'POST', * body: formData, * loadingMessage: '파일을 업로드하는 중...' * }) */ export const useApi = async ( path: string, options?: { // API 요청 옵션 method?: string; body?: any; headers?: Record; // 에러 처리 옵션 handleError?: boolean; // true: 에러를 null로 반환, false: 에러를 다시 던짐 showAlert?: boolean; // true: 에러 시 alert 표시 // 로딩 옵션 loadingMessage?: string; // 로딩 메시지 useGlobalLoading?: boolean; // 전역 로딩 사용 여부 (기본값: true) } ): Promise => { const { withLoading } = useLoading(); // API 호출 로직을 별도 함수로 분리 const apiCall = async (): Promise => { const { $api } = useNuxtApp(); // 기본값 설정 const { method = "GET", body, headers, handleError = true, showAlert = true, } = options || {}; // API 요청 옵션 구성 const apiOpts = { method, ...(body && { body }), ...(headers && { headers }), }; return ($api as any)(path, apiOpts).catch((error: any) => { // 사용자에게 알림 표시 if (showAlert) { const status = error.response?.status; let message = status === 404 ? "요청한 리소스를 찾을 수 없습니다." : status === 500 ? "서버 오류가 발생했습니다." : "요청 처리 중 오류가 발생했습니다."; // 서버에서 온 에러 메시지가 있으면 우선 사용 if (error.response?._data?.description) { message = error.response._data.description; } alert(message); } // 에러 처리 방식에 따라 반환 if (handleError) { return null as T; // 에러를 null로 반환 } else { throw error; // 에러를 다시 던짐 } }); }; // 전역 로딩 사용 여부 확인 (기본값: true) const shouldUseLoading = options?.useGlobalLoading !== false; if (shouldUseLoading) { // 전역 로딩과 함께 API 호출 return await withLoading( apiCall, options?.loadingMessage || "데이터를 불러오는 중..." ); } else { // 전역 로딩 없이 API 호출 return await apiCall(); } };