-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b9bc378
commit ba15ed6
Showing
8 changed files
with
223 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import buildURL from './buildURL'; | ||
import HTTP_METHOD from './httpMethod'; | ||
|
||
interface APIClientType { | ||
get<T>(path: string, queryParams?: Record<string, string>): Promise<T>; | ||
post<T>(path: string, body?: Record<string, any>): Promise<T>; | ||
patch<T>(path: string, body?: Record<string, any>): Promise<T>; | ||
delete(path: string): Promise<void>; | ||
} | ||
|
||
export default class APIClient implements APIClientType { | ||
private baseURL: URL; | ||
private header?: Headers; | ||
|
||
constructor(baseURL: string, header?: HeadersInit) { | ||
this.baseURL = new URL(baseURL); | ||
this.header = new Headers(header); | ||
} | ||
|
||
async get<T>(path: string, queryParams?: Record<string, string>): Promise<T> { | ||
return this.request<T>({ path, method: HTTP_METHOD.get, queryParams }); | ||
} | ||
|
||
async post<T>(path: string, body?: object): Promise<T> { | ||
return this.request<T>({ path, method: HTTP_METHOD.post, body }); | ||
} | ||
|
||
async patch<T>(path: string, body?: object): Promise<T> { | ||
return this.request<T>({ path, method: HTTP_METHOD.patch, body }); | ||
} | ||
|
||
async delete(path: string): Promise<void> { | ||
return this.request<void>({ path, method: HTTP_METHOD.delete }); | ||
} | ||
|
||
private async request<T>({ | ||
path, | ||
method, | ||
body, | ||
queryParams, | ||
}: { | ||
path: string; | ||
method: string; | ||
body?: Record<string, any>; | ||
queryParams?: Record<string, string>; | ||
}): Promise<T> { | ||
const url = buildURL({ baseURL: this.baseURL, path, queryParams }); | ||
|
||
const response = await fetch(url, { | ||
method, | ||
headers: this.header, | ||
body: JSON.stringify(body), | ||
}); | ||
|
||
if (!response.ok) { | ||
throw new Error(response.statusText); | ||
} | ||
|
||
const data = await response.json(); | ||
|
||
return data; | ||
} | ||
} |
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,16 @@ | ||
interface BuildURLParams { | ||
baseURL: URL; | ||
path?: string; | ||
queryParams?: Record<string, string>; | ||
} | ||
|
||
const buildURL = ({ baseURL, path, queryParams }: BuildURLParams): URL => { | ||
const url = new URL(baseURL); | ||
|
||
url.pathname = path ? path : ''; | ||
url.search = queryParams ? new URLSearchParams(queryParams).toString() : ''; | ||
|
||
return url; | ||
}; | ||
|
||
export default buildURL; |
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,10 @@ | ||
import { BASE_URL } from '../baseUrl'; | ||
import APIClient from './APIClient'; | ||
|
||
const API_URL = process.env.NODE_ENV === 'development' ? BASE_URL.dev : BASE_URL.prod; | ||
|
||
const header = { | ||
'Content-type': 'application/json', | ||
}; | ||
|
||
export const develupAPIClient = new APIClient(API_URL, header); |
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,8 @@ | ||
const HTTP_METHOD = { | ||
get: 'GET', | ||
post: 'POST', | ||
patch: 'PATCH', | ||
delete: 'DELETE', | ||
} as const; | ||
|
||
export default HTTP_METHOD; |
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,36 @@ | ||
import type { Mission } from '@/types'; | ||
import { develupAPIClient } from './clients/develupClient'; | ||
import { PATH } from './paths'; | ||
|
||
// 이 파일 내의 타입 선언 및 api 요청 로직은 APIClient 사용법을 설명하기 위한 예시 코드입니다. @라이언 | ||
interface Submission { | ||
id: number; | ||
memberId: number; | ||
missionId: number; | ||
url: string; | ||
comment: string; | ||
} | ||
|
||
interface GetMissionsResponse { | ||
data: Mission[]; | ||
} | ||
|
||
interface PostSubmissionResponse { | ||
data: Submission; | ||
} | ||
|
||
export const getMissions = async (queryParams?: Record<string, string>): Promise<Mission[]> => { | ||
const { data } = await develupAPIClient.get<GetMissionsResponse>(PATH.missionList, queryParams); | ||
|
||
return data; | ||
}; | ||
|
||
export const postSubmission = async (payload: { | ||
missionId: number; | ||
url: string; | ||
comment: string; | ||
}): Promise<Submission> => { | ||
const { data } = await develupAPIClient.post<PostSubmissionResponse>(PATH.submissions, payload); | ||
|
||
return data; | ||
}; |
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 |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export const PATH = { | ||
missionList: '/missions', | ||
submissions: '/submissions', | ||
}; |
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,79 @@ | ||
import { getMissions, postSubmission } from '@/apis/mission'; | ||
|
||
export default function APITestPage() { | ||
const testGetMissions = async () => { | ||
try { | ||
// ✅ getMissions 로직을 확인해주세요 | ||
const missions = await getMissions(); | ||
|
||
alert(`요청 성공! \n응답: ${JSON.stringify(missions)}`); | ||
} catch (err) { | ||
alert('요청 실패. console을 확인하세요.'); | ||
console.error(err); | ||
} | ||
}; | ||
|
||
const testGetMissionsWithQueryParams = async () => { | ||
try { | ||
// ✅ getMissions에 쿼리 파라미터를 넘기는 방식을 확인해주세요. | ||
const missions = await getMissions({ page: '1' }); | ||
|
||
alert(`요청 성공! \n응답: ${JSON.stringify(missions)}`); | ||
} catch (err) { | ||
alert('요청 실패. console을 확인하세요.'); | ||
console.error(err); | ||
} | ||
}; | ||
|
||
const testPostMissionSubmission = async () => { | ||
try { | ||
// ✅ postSubmission 로직을 확인해주세요 | ||
const createdSubmission = await postSubmission({ | ||
missionId: 999, | ||
url: 'www.develup.com', | ||
comment: '테스트용 데이터입니다 (언제든 지워도 됨)', | ||
}); | ||
alert(`요청 성공! \n응답: ${JSON.stringify(createdSubmission)}`); | ||
} catch (err) { | ||
alert('요청 실패. console을 확인하세요.'); | ||
console.error(err); | ||
} | ||
}; | ||
|
||
return ( | ||
<div> | ||
<button | ||
style={{ | ||
background: 'lightblue', | ||
fontSize: '5rem', | ||
cursor: 'pointer', | ||
}} | ||
onClick={testGetMissions} | ||
> | ||
get 요청 test 🤖 | ||
</button> | ||
<br /> | ||
<button | ||
style={{ | ||
background: 'lightblue', | ||
fontSize: '5rem', | ||
cursor: 'pointer', | ||
}} | ||
onClick={testGetMissionsWithQueryParams} | ||
> | ||
쿼리파라미터가 담긴 get 요청 test 🤖 | ||
</button> | ||
<br /> | ||
<button | ||
style={{ | ||
background: 'pink', | ||
fontSize: '5rem', | ||
cursor: 'pointer', | ||
}} | ||
onClick={testPostMissionSubmission} | ||
> | ||
post 요청 test 🤖 | ||
</button> | ||
</div> | ||
); | ||
} |