Skip to content

Commit 8e23a72

Browse files
committed
refactor: API 로직 코드 개선
1 parent 6e403de commit 8e23a72

17 files changed

+271
-228
lines changed

.env

Lines changed: 0 additions & 1 deletion
This file was deleted.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ node_modules
1111
dist
1212
dist-ssr
1313
*.local
14+
.env
1415

1516
# Editor directories and files
1617
.vscode/*

src/apis/client/interceptors.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { InternalAxiosRequestConfig } from "axios";
33
export const requestInterceptor = (
44
config: InternalAxiosRequestConfig,
55
): InternalAxiosRequestConfig => {
6-
const token = localStorage.getItem("token") ?? "";
6+
const token: string | null = localStorage.getItem("token");
77

88
if (token) {
99
config.headers.Authorization = `Bearer ${token}`;

src/apis/client/requestor.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ const requestor: AxiosInstance = axios.create({
1111
},
1212
});
1313

14-
requestor.interceptors.request.use(requestInterceptor, (error: AxiosError) =>
15-
Promise.reject(error),
16-
);
14+
requestor.interceptors.request.use(requestInterceptor, (error: AxiosError) => {
15+
return Promise.reject(error);
16+
});
1717

1818
export default requestor;

src/apis/services/alertService.tsx

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
11
import type { AxiosResponse } from "axios";
2-
import { AlertListResponse, AlertResponse } from "src/types";
2+
import { AlertListResponse, AlertReadListResponse } from "src/types";
33

44
import requestor from "../client/requestor";
55

6-
class AlertService {
7-
getAlerts(
8-
userId: string,
9-
offset?: number,
10-
limit?: number,
11-
): Promise<AxiosResponse<AlertListResponse>> {
12-
return requestor.get(`/users/${userId}/alerts`, {
13-
params: { offset, limit },
14-
});
15-
}
6+
/* 유저의 알림 목록 조회 */
7+
export const getAlerts = (
8+
userId: string,
9+
offset: number = 0,
10+
limit?: number,
11+
): Promise<AxiosResponse<AlertListResponse>> => {
12+
return requestor.get(`/users/${userId}/alerts`, {
13+
params: { offset, limit },
14+
});
15+
};
1616

17-
putAlert(
18-
userId: string,
19-
alertId: string,
20-
): Promise<AxiosResponse<AlertResponse>> {
21-
return requestor.put(`/users/${userId}/alerts/${alertId}`);
22-
}
23-
}
24-
25-
export default new AlertService();
17+
/* 알림 읽음 처리 */
18+
export const putAlert = (
19+
userId: string,
20+
alertId: string,
21+
): Promise<AxiosResponse<AlertReadListResponse>> => {
22+
return requestor.put(`/users/${userId}/alerts/${alertId}`);
23+
};

src/apis/services/applicationService.tsx

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,51 @@ import {
33
ApplicationListResponse,
44
ApplicationResponse,
55
ApplicationStatus,
6+
UserApplicationListResponse,
67
} from "src/types";
78

89
import requestor from "../client/requestor";
910

10-
class ApplicationService {
11-
getShopApplications(
12-
shopId: string,
13-
noticeId: string,
14-
offset?: number,
15-
limit?: number,
16-
): Promise<AxiosResponse<ApplicationListResponse>> {
17-
return requestor.get(`/shops/${shopId}/notices/${noticeId}/applications`, {
18-
params: { offset, limit },
19-
});
20-
}
11+
/* 가게의 특정 공고의 지원 목록 조회 */
12+
export const getShopApplications = (
13+
shopId: string,
14+
noticeId: string,
15+
offset?: number,
16+
limit?: number,
17+
): Promise<AxiosResponse<ApplicationListResponse>> => {
18+
return requestor.get(`/shops/${shopId}/notices/${noticeId}/applications`, {
19+
params: { offset, limit },
20+
});
21+
};
2122

22-
postApplication(
23-
shopId: string,
24-
noticeId: string,
25-
): Promise<AxiosResponse<ApplicationResponse>> {
26-
return requestor.post(`/shops/${shopId}/notices/${noticeId}/applications`);
27-
}
23+
/* 가게의 특정 공고 지원 등록 */
24+
export const postApplication = (
25+
shopId: string,
26+
noticeId: string,
27+
): Promise<AxiosResponse<ApplicationResponse>> => {
28+
return requestor.post(`/shops/${shopId}/notices/${noticeId}/applications`);
29+
};
2830

29-
putApplication(
30-
shopId: string,
31-
noticeId: string,
32-
applicationId: string,
33-
status: Exclude<ApplicationStatus, "pending">,
34-
): Promise<AxiosResponse<ApplicationResponse>> {
35-
return requestor.put(
36-
`/shops/${shopId}/notices/${noticeId}/applications/${applicationId}`,
37-
{ status },
38-
);
39-
}
31+
/* 가게의 특정 공고 지원 승인, 거절 또는 취소소 */
32+
export const putApplication = (
33+
shopId: string,
34+
noticeId: string,
35+
applicationId: string,
36+
status: Exclude<ApplicationStatus, "pending">,
37+
): Promise<AxiosResponse<ApplicationResponse>> => {
38+
return requestor.put(
39+
`/shops/${shopId}/notices/${noticeId}/applications/${applicationId}`,
40+
{ status },
41+
);
42+
};
4043

41-
getUserApplications(
42-
userId: string,
43-
offset?: number,
44-
limit?: number,
45-
): Promise<AxiosResponse<ApplicationListResponse>> {
46-
return requestor.get(`/users/${userId}/applications`, {
47-
params: { offset, limit },
48-
});
49-
}
50-
}
51-
52-
export default new ApplicationService();
44+
/* 유저의 지원 목록 조회 */
45+
export const getUserApplications = (
46+
userId: string,
47+
offset?: number,
48+
limit?: number,
49+
): Promise<AxiosResponse<UserApplicationListResponse>> => {
50+
return requestor.get(`/users/${userId}/applications`, {
51+
params: { offset, limit },
52+
});
53+
};
Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,44 @@
11
import type { AxiosResponse } from "axios";
2-
import type { UserItem } from "src/types";
2+
import type { ApiWithHref, UserItem } from "src/types";
33
import { ApiWrapper } from "src/types";
44

55
import requestor from "../client/requestor";
66

77
interface LoginItem {
88
token: string;
9-
user: ApiWrapper<UserItem>;
9+
user: ApiWithHref<UserItem>;
1010
}
1111

1212
export type LoginRequest = { email: string; password: string };
1313
export type LoginResponse = ApiWrapper<LoginItem>;
1414

15-
class AuthenticationService {
16-
async postAuthentication(
17-
payload: LoginRequest,
18-
): Promise<AxiosResponse<LoginResponse>> {
19-
const res = await requestor.post<LoginResponse>("/token", payload);
20-
21-
const token = res.data.item.token;
22-
const user = res.data.item.user.item;
23-
24-
localStorage.setItem("token", token);
25-
localStorage.setItem("user", JSON.stringify(user));
26-
27-
return res;
28-
}
29-
30-
logout() {
31-
localStorage.removeItem("token");
32-
localStorage.removeItem("user");
33-
}
34-
35-
getToken() {
36-
return localStorage.getItem("token");
37-
}
38-
isAuthenticated() {
39-
return Boolean(this.getToken());
40-
}
41-
getUser(): UserItem | null {
42-
const raw = localStorage.getItem("user");
43-
return raw ? (JSON.parse(raw) as UserItem) : null;
44-
}
45-
}
15+
/* 로그인 */
16+
export const postAuthentication = async (
17+
payload: LoginRequest,
18+
): Promise<AxiosResponse<LoginResponse>> => {
19+
const res = await requestor.post<LoginResponse>("/token", payload);
20+
21+
const token = res.data.item.token;
22+
const user = res.data.item.user.item;
23+
24+
localStorage.setItem("token", token);
25+
localStorage.setItem("user", JSON.stringify(user));
26+
27+
return res;
28+
};
29+
30+
/* 로그아웃 */
31+
export const logout = () => {
32+
localStorage.removeItem("token");
33+
localStorage.removeItem("user");
34+
};
35+
36+
/* 토큰 반환 */
37+
export const getToken = () => {
38+
return localStorage.getItem("token");
39+
};
4640

47-
export default new AuthenticationService();
41+
/* 인증 여부 확인 */
42+
export const isAuthenticated = () => {
43+
return Boolean(getToken());
44+
};

src/apis/services/imageService.tsx

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,31 @@ interface PresignedItem {
88
}
99
type PresignedResponse = ApiWrapper<PresignedItem>;
1010

11-
class ImageService {
12-
async postImage(name: string): Promise<string> {
13-
const res: AxiosResponse<PresignedResponse> = await requestor.post(
14-
"/images",
15-
{ name },
16-
);
17-
return res.data.item.url;
18-
}
11+
/* Presigned URL 생성 */
12+
export const postImage = async (name: string): Promise<string> => {
13+
const res: AxiosResponse<PresignedResponse> = await requestor.post(
14+
"/images",
15+
{ name },
16+
);
17+
return res.data.item.url;
18+
};
1919

20-
async putImage(
21-
presignedURL: string,
22-
file: File | Blob,
23-
): Promise<AxiosResponse<void>> {
24-
return axios.put(presignedURL, file, {
25-
headers: { "Content-Type": file.type || "application/octet-stream" },
26-
});
27-
}
20+
/* S3로 이미지 업로드 */
21+
export const putImage = async (
22+
presignedURL: string,
23+
file: File | Blob,
24+
): Promise<AxiosResponse<void>> => {
25+
return axios.put(presignedURL, file, {
26+
headers: { "Content-Type": file.type || "application/octet-stream" },
27+
});
28+
};
2829

29-
getPublicURL(presignedURL: string) {
30-
return presignedURL.split("?")[0];
31-
}
32-
getImage(publicURL: string): Promise<AxiosResponse<Blob>> {
33-
return axios.get(publicURL, { responseType: "blob" });
34-
}
35-
}
30+
/* Presigned URL 조회 */
31+
export const getPublicURL = (presignedURL: string) => {
32+
return presignedURL.split("?")[0];
33+
};
3634

37-
export default new ImageService();
35+
/* 이미지 조회 */
36+
export const getImage = (publicURL: string): Promise<AxiosResponse<Blob>> => {
37+
return axios.get(publicURL, { responseType: "blob" });
38+
};

0 commit comments

Comments
 (0)