-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FE] - api 통신을 위한 apiClient 구현 (#55)
* feat: API 기본 세팅 추가 - api를 endPoint만 작성하면 쉽게 호출 가능한 형태의 함수인 apiClient 추가 - AbortController를 통해 요청 제한 시간 추가 * feat: apiClient를 axios와 비슷한 형태로 사용가능하도록 수정 - body의 경우 객체 상태로 넘길 수 있도록 타입 설정 * feat: react-query QueryClientProvider 설정 추가
- Loading branch information
Showing
3 changed files
with
64 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// TODO: env 파일로 관리하기 | ||
const BASE_URL = 'http://localhost:3000/'; | ||
|
||
interface FetchOptions extends Omit<RequestInit, 'body'> { | ||
headers?: Record<string, string>; | ||
body?: unknown; | ||
} | ||
|
||
export const apiClient = { | ||
get: (endPoint: string, options: FetchOptions = {}) => | ||
sendRequest(endPoint, { ...options, method: 'GET' }), | ||
post: (endPoint: string, options: FetchOptions = {}) => | ||
sendRequest(endPoint, { ...options, method: 'POST' }), | ||
put: (endPoint: string, options: FetchOptions = {}) => | ||
sendRequest(endPoint, { ...options, method: 'PUT' }), | ||
delete: (endPoint: string, options: FetchOptions = {}) => | ||
sendRequest(endPoint, { ...options, method: 'DELETE' }), | ||
}; | ||
|
||
async function sendRequest(endPoint: string, options: FetchOptions = {}, timeout: number = 10000) { | ||
const { headers, body, ...restOptions } = options; | ||
|
||
const abortController = new AbortController(); | ||
const timeoutId = setTimeout(() => { | ||
abortController.abort(); | ||
}, timeout); | ||
|
||
try { | ||
const response = await fetch(`${BASE_URL}${endPoint}`, { | ||
headers: { | ||
'Content-Type': 'application/json', | ||
Authorization: `Bearer ${localStorage.getItem('token')}`, | ||
...headers, | ||
}, | ||
// axios처럼 객체를 body로 받을 수 있도록 설정 | ||
...(body !== undefined && | ||
body !== null && { | ||
body: typeof body === 'object' ? JSON.stringify(body) : (body as BodyInit), | ||
}), | ||
signal: abortController.signal, | ||
...restOptions, | ||
}); | ||
|
||
if (!response.ok) { | ||
const errorMessage = await response.text(); | ||
throw new Error(errorMessage || 'API 요청 실패'); | ||
} | ||
return response.json(); | ||
} catch (error) { | ||
if (error instanceof Error && error.name === 'AbortError') { | ||
throw new Error('요청 시간이 초과되었습니다.'); | ||
} | ||
throw error; | ||
} finally { | ||
clearTimeout(timeoutId); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters