문제 인식
API response의 공통 타입은 이러합니다.
typescript
type CommonResponse<T> = { code: string; message: string; data: T; };
그래서 Axios로 API를 모듈화 할 때 다음과 같이 제네릭 타입을 반복적으로 작성해야 하는 불편함이 있었습니다. 그리고 구조분해할당해서 가져온 data를 가져와서 한뎁스 더 들어가서 return 해주어야 했어요.
typescript
export const authApi = { getLogin: async (code: string, provider: string) => { const { data } = await instance.get<CommonResponse<LoginResponse>>(`/auth/login?code=${code}&provider=${provider}`); return data.data; }, };
해결 과정
다음과 같이 Axios instance를 http 메서드 별로 한 번 더 래핑하는 객체를 작성했습니다.
typescript
const getResponseFromBody = <T>(response: AxiosResponse<CommonResponse<T>>): T => { const { data: body } = response; return body.data; }; const http = { get: <T = unknown>(...args: Parameters<Axios['get']>) => instance.get<CommonResponse<T>>(...args).then(getResponseFromBody), post: <T = unknown>(...args: Parameters<Axios['post']>) => instance.post<CommonResponse<T>>(...args).then(getResponseFromBody), patch: <T = unknown>(...args: Parameters<Axios['patch']>) => instance.patch<CommonResponse<T>>(...args).then(getResponseFromBody), put: <T = unknown>(...args: Parameters<Axios['put']>) => instance.put<CommonResponse<T>>(...args).then(getResponseFromBody), delete: <T = unknown>(...args: Parameters<Axios['delete']>) => instance.delete<CommonResponse<T>>(...args).then(getResponseFromBody), };
기본적으로 제네릭 타입으로 넘어온 타입이 CommponResponse의 generic 타입으로 넘어가게 됩니다. 그리고 리턴하는 Promise를 then 체이닝에서 getResponseFormBody가 response.data.data
의 값을 반환하도록 하고 있어요.
훨씬 말끔해졌습니다!