Refactor: api 리팩토링

This commit is contained in:
정현조 2024-09-12 10:42:03 +09:00
parent aa074ad148
commit 3e7981d8ba
4 changed files with 164 additions and 128 deletions

View File

@ -1,13 +1,28 @@
import api from '@/api/axiosConfig';
import { AxiosError } from 'axios';
import { AxiosError, AxiosResponse } from 'axios';
import { SuccessResponse, MemberResponseDTO, RefreshTokenResponseDTO } from '@/types';
export const reissueTokenApi = () => {
return api.post('/api/auth/reissue', null, { withCredentials: true }).then((response) => response.data);
export const reissueTokenApi = async (): Promise<SuccessResponse<RefreshTokenResponseDTO>> => {
try {
const response: AxiosResponse<SuccessResponse<RefreshTokenResponseDTO>> = await api.post(
'/api/auth/reissue',
null,
{ withCredentials: true }
);
return response.data;
} catch (error) {
if (error instanceof AxiosError) {
console.error('토큰 재발급 실패:', error.response?.data?.message || '알 수 없는 오류');
} else {
console.error('알 수 없는 오류가 발생했습니다.');
}
throw error;
}
};
export const fetchProfileApi = async () => {
export const fetchProfileApi = async (): Promise<SuccessResponse<MemberResponseDTO>> => {
try {
const response = await api.get('/api/auth/profile', {
const response: AxiosResponse<SuccessResponse<MemberResponseDTO>> = await api.get('/api/auth/profile', {
withCredentials: true,
});
return response.data;

View File

@ -1,5 +1,6 @@
import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import useAuthStore from '@/stores/useAuthStore';
import { BaseResponse, CustomError, SuccessResponse, RefreshTokenResponseDTO } from '@/types';
const baseURL = 'https://j11s002.p.ssafy.io';
@ -38,7 +39,7 @@ api.interceptors.request.use((config: InternalAxiosRequestConfig) => {
api.interceptors.response.use(
(response: AxiosResponse) => response,
async (error: AxiosError) => {
async (error: AxiosError<BaseResponse<CustomError>>) => {
const originalRequest = error.config as InternalAxiosRequestConfig & { _retry?: boolean };
if (error.response?.status === 401 && !originalRequest._retry) {
@ -58,45 +59,55 @@ api.interceptors.response.use(
originalRequest._retry = true;
isTokenRefreshing = true;
return api
.post('/api/auth/reissue', null, { withCredentials: true })
.then((response) => {
const newAccessToken = response.data?.data?.accessToken;
if (!newAccessToken) {
throw new Error('Invalid token reissue response');
}
try {
const response: AxiosResponse<SuccessResponse<RefreshTokenResponseDTO>> = await api.post(
'/api/auth/reissue',
null,
{ withCredentials: true }
);
useAuthStore.getState().setLoggedIn(true, newAccessToken);
localStorage.setItem('accessToken', newAccessToken);
processQueue(null, newAccessToken);
const newAccessToken = response.data.data?.accessToken;
if (!newAccessToken) {
throw new Error('Invalid token reissue response');
}
if (originalRequest.headers) {
originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
}
return api(originalRequest);
})
.catch((reissueError: Error) => {
processQueue(reissueError, undefined);
console.error('토큰 재발급 실패:', reissueError);
useAuthStore.getState().clearAuth();
window.location.href = '/';
return Promise.reject(reissueError);
})
.finally(() => {
isTokenRefreshing = false;
});
useAuthStore.getState().setLoggedIn(true, newAccessToken);
localStorage.setItem('accessToken', newAccessToken);
processQueue(null, newAccessToken);
if (originalRequest.headers) {
originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
}
return api(originalRequest);
} catch (reissueError: unknown) {
processQueue(reissueError as Error, undefined);
console.error('토큰 재발급 실패:', reissueError);
useAuthStore.getState().clearAuth();
window.location.href = '/';
return Promise.reject(reissueError);
} finally {
isTokenRefreshing = false;
}
}
if (error.response?.status === 400) {
alert('잘못된 요청입니다. 다시 시도해 주세요.');
} else if (error.response?.status === 403) {
alert('권한이 없습니다. 다시 로그인해 주세요.');
useAuthStore.getState().clearAuth();
window.location.href = '/';
}
handleCommonErrors(error);
return Promise.reject(error);
}
);
const handleCommonErrors = (error: AxiosError<BaseResponse<CustomError>>) => {
if (error.response?.status === 400) {
alert('잘못된 요청입니다. 다시 시도해 주세요.');
} else if (error.response?.status === 403) {
alert('권한이 없습니다. 다시 로그인해 주세요.');
useAuthStore.getState().clearAuth();
window.location.href = '/';
} else {
console.error('오류 발생:', error.response?.data?.message || '알 수 없는 오류');
useAuthStore.getState().clearAuth();
window.location.href = '/';
}
};
export default api;

View File

@ -1,12 +1,11 @@
import api from '@/api/axiosConfig';
import { AxiosError } from 'axios';
import { AxiosError, AxiosResponse } from 'axios';
import { BaseResponse, ProjectResponseDTO, ProjectListResponseDTO } from '@/types';
export const getProjectApi = async (projectId: number, memberId: number) => {
export const getProjectApi = async (projectId: number, memberId: number): Promise<BaseResponse<ProjectResponseDTO>> => {
try {
const response = await api.get(`/api/projects/${projectId}`, {
params: {
memberId,
},
const response: AxiosResponse<BaseResponse<ProjectResponseDTO>> = await api.get(`/api/projects/${projectId}`, {
params: { memberId },
});
return response.data;
} catch (error) {
@ -22,14 +21,16 @@ export const getProjectApi = async (projectId: number, memberId: number) => {
export const updateProjectApi = async (
projectId: number,
memberId: number,
data: { title: string; projectType: string }
) => {
data: { title: string; projectType: 'classification' | 'detection' | 'segmentation' }
): Promise<BaseResponse<ProjectResponseDTO>> => {
try {
const response = await api.put(`/api/projects/${projectId}`, data, {
params: {
memberId,
},
});
const response: AxiosResponse<BaseResponse<ProjectResponseDTO>> = await api.put(
`/api/projects/${projectId}`,
data,
{
params: { memberId },
}
);
return response.data;
} catch (error) {
if (error instanceof AxiosError) {
@ -41,12 +42,10 @@ export const updateProjectApi = async (
}
};
export const deleteProjectApi = async (projectId: number, memberId: number) => {
export const deleteProjectApi = async (projectId: number, memberId: number): Promise<BaseResponse<null>> => {
try {
const response = await api.delete(`/api/projects/${projectId}`, {
params: {
memberId,
},
const response: AxiosResponse<BaseResponse<null>> = await api.delete(`/api/projects/${projectId}`, {
params: { memberId },
});
return response.data;
} catch (error) {
@ -64,15 +63,13 @@ export const addProjectMemberApi = async (
memberId: number,
newMemberId: number,
privilegeType: string
) => {
): Promise<BaseResponse<null>> => {
try {
const response = await api.post(
const response: AxiosResponse<BaseResponse<null>> = await api.post(
`/api/projects/${projectId}/members`,
{ memberId: newMemberId, privilegeType },
{
params: {
memberId,
},
params: { memberId },
}
);
return response.data;
@ -86,12 +83,14 @@ export const addProjectMemberApi = async (
}
};
export const removeProjectMemberApi = async (projectId: number, memberId: number, targetMemberId: number) => {
export const removeProjectMemberApi = async (
projectId: number,
memberId: number,
targetMemberId: number
): Promise<BaseResponse<null>> => {
try {
const response = await api.delete(`/api/projects/${projectId}/members`, {
params: {
memberId,
},
const response: AxiosResponse<BaseResponse<null>> = await api.delete(`/api/projects/${projectId}/members`, {
params: { memberId },
data: { memberId: targetMemberId },
});
return response.data;
@ -110,15 +109,18 @@ export const getAllProjectsApi = async (
memberId: number,
lastProjectId?: number,
limit: number = 10
) => {
): Promise<BaseResponse<ProjectListResponseDTO>> => {
try {
const response = await api.get(`/api/workspaces/${workspaceId}/projects`, {
params: {
memberId,
lastProjectId,
limit,
},
});
const response: AxiosResponse<BaseResponse<ProjectListResponseDTO>> = await api.get(
`/api/workspaces/${workspaceId}/projects`,
{
params: {
memberId,
lastProjectId,
limit,
},
}
);
return response.data;
} catch (error) {
if (error instanceof AxiosError) {
@ -133,14 +135,16 @@ export const getAllProjectsApi = async (
export const createProjectApi = async (
workspaceId: number,
memberId: number,
data: { title: string; projectType: string }
) => {
data: { title: string; projectType: 'classification' | 'detection' | 'segmentation' }
): Promise<BaseResponse<ProjectResponseDTO>> => {
try {
const response = await api.post(`/api/workspaces/${workspaceId}/projects`, data, {
params: {
memberId,
},
});
const response: AxiosResponse<BaseResponse<ProjectResponseDTO>> = await api.post(
`/api/workspaces/${workspaceId}/projects`,
data,
{
params: { memberId },
}
);
return response.data;
} catch (error) {
if (error instanceof AxiosError) {

View File

@ -1,34 +1,18 @@
import api from '@/api/axiosConfig';
import { AxiosError } from 'axios';
import { AxiosError, AxiosResponse } from 'axios';
import { BaseResponse, WorkspaceRequestDTO, WorkspaceResponseDTO, WorkspaceListResponseDTO } from '@/types';
interface Workspace {
id: number;
memberId: string;
title: string;
content: string;
createdAt: string;
updatedAt: string;
}
interface GetAllWorkspacesResponse {
status: number;
code: number;
message: string;
data: {
workspaceResponses: Workspace[];
};
errors: Array<{
field: string;
code: string;
message: string;
objectName: string;
}>;
isSuccess: boolean;
}
export const getWorkspaceApi = async (workspaceId: number, memberId: number) => {
export const getWorkspaceApi = async (
workspaceId: number,
memberId: number
): Promise<BaseResponse<WorkspaceResponseDTO>> => {
try {
const response = await api.get(`/api/workspaces/${workspaceId}`, {
params: { memberId },
});
const response: AxiosResponse<BaseResponse<WorkspaceResponseDTO>> = await api.get(
`/api/workspaces/${workspaceId}`,
{
params: { memberId },
}
);
return response.data;
} catch (error) {
if (error instanceof AxiosError) {
@ -43,12 +27,16 @@ export const getWorkspaceApi = async (workspaceId: number, memberId: number) =>
export const updateWorkspaceApi = async (
workspaceId: number,
memberId: number,
data: { title: string; content: string }
) => {
data: WorkspaceRequestDTO
): Promise<BaseResponse<WorkspaceResponseDTO>> => {
try {
const response = await api.put(`/api/workspaces/${workspaceId}`, data, {
params: { memberId },
});
const response: AxiosResponse<BaseResponse<WorkspaceResponseDTO>> = await api.put(
`/api/workspaces/${workspaceId}`,
data,
{
params: { memberId },
}
);
return response.data;
} catch (error) {
if (error instanceof AxiosError) {
@ -60,9 +48,9 @@ export const updateWorkspaceApi = async (
}
};
export const deleteWorkspaceApi = async (workspaceId: number, memberId: number) => {
export const deleteWorkspaceApi = async (workspaceId: number, memberId: number): Promise<BaseResponse<null>> => {
try {
const response = await api.delete(`/api/workspaces/${workspaceId}`, {
const response: AxiosResponse<BaseResponse<null>> = await api.delete(`/api/workspaces/${workspaceId}`, {
params: { memberId },
});
return response.data;
@ -80,9 +68,9 @@ export const getAllWorkspacesApi = async (
memberId: number,
lastWorkspaceId?: number,
limit?: number
): Promise<GetAllWorkspacesResponse> => {
): Promise<BaseResponse<WorkspaceListResponseDTO>> => {
try {
const response = await api.get('/api/workspaces', {
const response: AxiosResponse<BaseResponse<WorkspaceListResponseDTO>> = await api.get('/api/workspaces', {
params: { memberId, lastWorkspaceId, limit },
});
return response.data;
@ -96,9 +84,12 @@ export const getAllWorkspacesApi = async (
}
};
export const createWorkspaceApi = async (memberId: number, data: { title: string; content: string }) => {
export const createWorkspaceApi = async (
memberId: number,
data: WorkspaceRequestDTO
): Promise<BaseResponse<WorkspaceResponseDTO>> => {
try {
const response = await api.post('/api/workspaces', data, {
const response: AxiosResponse<BaseResponse<WorkspaceResponseDTO>> = await api.post('/api/workspaces', data, {
params: { memberId },
});
return response.data;
@ -112,11 +103,19 @@ export const createWorkspaceApi = async (memberId: number, data: { title: string
}
};
export const addWorkspaceMemberApi = async (workspaceId: number, memberId: number, newMemberId: number) => {
export const addWorkspaceMemberApi = async (
workspaceId: number,
memberId: number,
newMemberId: number
): Promise<BaseResponse<null>> => {
try {
const response = await api.post(`/api/workspaces/${workspaceId}/members/${newMemberId}`, null, {
params: { memberId },
});
const response: AxiosResponse<BaseResponse<null>> = await api.post(
`/api/workspaces/${workspaceId}/members/${newMemberId}`,
null,
{
params: { memberId },
}
);
return response.data;
} catch (error) {
if (error instanceof AxiosError) {
@ -128,11 +127,18 @@ export const addWorkspaceMemberApi = async (workspaceId: number, memberId: numbe
}
};
export const removeWorkspaceMemberApi = async (workspaceId: number, memberId: number, targetMemberId: number) => {
export const removeWorkspaceMemberApi = async (
workspaceId: number,
memberId: number,
targetMemberId: number
): Promise<BaseResponse<null>> => {
try {
const response = await api.delete(`/api/workspaces/${workspaceId}/members/${targetMemberId}`, {
params: { memberId },
});
const response: AxiosResponse<BaseResponse<null>> = await api.delete(
`/api/workspaces/${workspaceId}/members/${targetMemberId}`,
{
params: { memberId },
}
);
return response.data;
} catch (error) {
if (error instanceof AxiosError) {