Skip to content

Commit a80451d

Browse files
authored
✨ api 모듈 생성 (#16)
* 🐛 vite가 alias 파싱할 수 있도록 수정 및 src를 @의 루트로 설정 * 🐛 tailwindcss가 파일명 오타로 적용되지 않는 버그 해결 * ✨ shadcn/ui로 카드, input, label, tab 컴포넌트 임포트 * ✨ 로그인 및 회원가입 UI 생성 * ✨ api 모듈 생성 * 🎨 마지막 출 추가 포매팅 적용
1 parent cdfc63e commit a80451d

6 files changed

Lines changed: 137 additions & 0 deletions

File tree

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type {
2+
ErrorResponse,
3+
InternalCallParams,
4+
ResponseNecessary,
5+
SuccessResponse,
6+
} from '../../domain';
7+
import type { TestRequest, TestResponse } from './schemas';
8+
9+
type GetApisProps = {
10+
callWithToken: <R extends ResponseNecessary>(
11+
p: InternalCallParams & { token: string }
12+
) => Promise<R | ErrorResponse>;
13+
callWithoutToken: <R extends ResponseNecessary>(
14+
p: InternalCallParams & { token?: never }
15+
) => Promise<R | ErrorResponse>;
16+
callWithOptionalToken: <R extends ResponseNecessary>(
17+
p: InternalCallParams & { token?: string }
18+
) => Promise<R | ErrorResponse>;
19+
};
20+
21+
type Api = (_: {
22+
body: never;
23+
token: string;
24+
params: never;
25+
query: never;
26+
}) => Promise<{ status: number; data: unknown }>;
27+
28+
export const getLocalServerApis = ({ callWithoutToken }: GetApisProps) =>
29+
({
30+
'GET /test': ({ body }: { body: TestRequest }) =>
31+
callWithoutToken<SuccessResponse<TestResponse>>({
32+
method: 'GET',
33+
path: 'test',
34+
body,
35+
}),
36+
}) satisfies Record<string, Api>;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { getLocalServerApis } from './apis';
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export type TestRequest = {
2+
test: number;
3+
};
4+
5+
export type TestResponse = {
6+
message: string;
7+
};

src/infrastructure/api/client.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { getLocalServerApis } from './apis/local-server';
2+
import type {
3+
ErrorResponse,
4+
ExternalCallParams,
5+
InternalCallParams,
6+
ResponseNecessary,
7+
} from './domain';
8+
9+
type ImplApiProps = {
10+
externalCall(_: ExternalCallParams): Promise<ResponseNecessary>;
11+
};
12+
13+
export const implApi = ({ externalCall }: ImplApiProps) => {
14+
const internalCall = async <R extends ResponseNecessary>(content: {
15+
method: string;
16+
path: string;
17+
body?: Record<string, unknown>;
18+
token?: string;
19+
}) => {
20+
const response = await externalCall({
21+
method: content.method,
22+
path: content.path,
23+
body: content.body,
24+
headers: {
25+
'content-type': 'application/json;charset=UTF-8',
26+
...(content.token !== undefined
27+
? { Authorization: `Bearer ${content.token}` }
28+
: {}),
29+
},
30+
credentials: 'include',
31+
});
32+
33+
return response as R;
34+
};
35+
36+
const callWithToken = <R extends ResponseNecessary>(
37+
p: InternalCallParams & { token: string }
38+
) => internalCall<R | ErrorResponse>(p);
39+
40+
const callWithoutToken = <R extends ResponseNecessary>(
41+
p: InternalCallParams & { token?: never }
42+
) => internalCall<R | ErrorResponse>(p);
43+
44+
const callWithOptionalToken = <R extends ResponseNecessary>(
45+
p: InternalCallParams & { token?: string }
46+
) => internalCall<R | ErrorResponse>(p);
47+
48+
return getLocalServerApis({
49+
callWithToken,
50+
callWithoutToken,
51+
callWithOptionalToken,
52+
});
53+
};
54+
55+
export type Apis = ReturnType<typeof getLocalServerApis>;

src/infrastructure/api/domain.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
export type ResponseNecessary = {
2+
status: number;
3+
data: unknown;
4+
};
5+
6+
// TODO: 200 이외의 코드가 내려왔을 때 대응 필요
7+
export type SuccessResponse<T, Status extends number = 200> = {
8+
status: Status;
9+
data: T;
10+
};
11+
12+
export type ErrorResponse<
13+
Status extends number = 400 | 401 | 403 | 404 | 409 | 500,
14+
> = {
15+
status: Status;
16+
data: {
17+
timestamp: string;
18+
message: string;
19+
code: string;
20+
};
21+
};
22+
23+
export type ExternalCallParams = {
24+
method: string;
25+
path: string;
26+
body?: Record<string, unknown>;
27+
headers?: Record<string, string>;
28+
credentials?: string;
29+
};
30+
31+
export type InternalCallParams = {
32+
method: string;
33+
path: string;
34+
body?: Record<string, unknown>;
35+
token?: string;
36+
};

src/infrastructure/api/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { type Apis, implApi } from './client';
2+
export type { ExternalCallParams } from './domain';

0 commit comments

Comments
 (0)