Skip to content

Commit

Permalink
feat : 회원가입 api와 훅을 추가합니다.
Browse files Browse the repository at this point in the history
  • Loading branch information
hhhminme committed Sep 20, 2023
1 parent 00b7d3c commit cef1c9f
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 29 deletions.
13 changes: 13 additions & 0 deletions apps/web/app/(auth)/_api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { http } from "../../../lib/http";
import { UserSchema } from "../_types";
import type { UserType, RegisterReq, UserErrorType } from "../_types";

export function register(req: RegisterReq): Promise<UserType | UserErrorType | undefined> {
return http.post({
url: "/users",
body: {
user: req,
},
schema: UserSchema,
});
}
9 changes: 9 additions & 0 deletions apps/web/app/(auth)/_hooks/use-register.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useMutation } from "@tanstack/react-query";
import type { RegisterReq } from "../_types";
import { register } from "../_api";

export function useRegister() {
return useMutation({
mutationFn: (req: RegisterReq) => register(req),
});
}
28 changes: 28 additions & 0 deletions apps/web/app/(auth)/_types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { z } from "zod";

export interface RegisterReq {
username: string;
email: string;
password: string;
}

export const UserErrorsSchema = z.object({
errors: z.object({
email: z.array(z.string()),
username: z.array(z.string()),
}),
});

export const UserSchema = z.object({
user: z.object({
email: z.string(),
token: z.string(),
username: z.string(),
bio: z.string(),
image: z.string(),
}),
});

export type UserErrorType = z.infer<typeof UserErrorsSchema>;

export type UserType = z.infer<typeof UserSchema>;
54 changes: 25 additions & 29 deletions apps/web/lib/http.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import type { z, ZodType } from "zod";
import { ZodError } from "zod";
import { UserErrorsSchema } from "../app/(auth)/_types";

const HTTP_ERRORS = {
BAD_REQUEST: "잘못된 요청: 요청이 잘못되었습니다.",
UNAUTHORIZED: "인증되지 않음: 인증이 필요합니다.",
FORBIDDEN: "금지됨 : 이 리소스에 액세스 권한이 없습니다.",
NOT_FOUND: "찾을 수 없음: 요청한 리소스를 찾을 수 없습니다.",
INTERNAL_SERVER_ERROR: "내부 서버 오류: 서버에서 오류가 발생했습니다.",
ALREADY_TOKEN: "토큰 : 이미 토큰이 있습니다.",
};

export const httpErrorHandler = (e: unknown, statusCode?: number): never => {
Expand All @@ -19,6 +21,8 @@ export const httpErrorHandler = (e: unknown, statusCode?: number): never => {
throw new Error(HTTP_ERRORS.FORBIDDEN);
case 404:
throw new Error(HTTP_ERRORS.NOT_FOUND);
case 422:
throw new Error(HTTP_ERRORS.ALREADY_TOKEN);
case 500:
throw new Error(HTTP_ERRORS.INTERNAL_SERVER_ERROR);
default:
Expand Down Expand Up @@ -46,23 +50,19 @@ export const buildUrl = (url: string): string => `${"https://api.realworld.io/ap

export const http = {
async get<Response>({ url, accessToken, schema }: { url: string; accessToken?: string; schema: ZodType<Response> }) {
try {
const headers = createHeaders(accessToken);
const headers = createHeaders(accessToken);

const res = await fetch(buildUrl(url), {
method: "GET",
headers,
});
const res = await fetch(buildUrl(url), {
method: "GET",
headers,
});

if (!res.ok) {
httpErrorHandler(new Error(`HTTP Error: ${res.statusText}`), res.status);
}

const obj: z.infer<typeof schema> = schema.parse(await res.json());
return obj;
} catch (e) {
httpErrorHandler(e);
if (!res.ok) {
httpErrorHandler(new Error(`HTTP Error: ${res.statusText}`), res.status);
}

const obj = schema.parse(await res.json());
return obj;
},
async post<Request, Response>({
url,
Expand All @@ -75,23 +75,19 @@ export const http = {
schema: ZodType<Response>;
body: Request;
}) {
try {
const headers = createHeaders(accessToken);
const headers = createHeaders(accessToken);

const res = await fetch(buildUrl(url), {
method: "POST",
headers,
body: JSON.stringify(body),
});
const res = await fetch(buildUrl(url), {
method: "POST",
headers,
body: JSON.stringify(body),
});

if (!res.ok) {
httpErrorHandler(new Error(`HTTP Error: ${res.statusText}`), res.status);
}

const obj: z.infer<typeof schema> = schema.parse(await res.json());
return obj;
} catch (e) {
httpErrorHandler(e);
if (!res.ok) {
httpErrorHandler(new Error(`HTTP Error: ${res.statusText}`), res.status);
}

const obj = schema.parse(await res.json());
return obj;
},
};

0 comments on commit cef1c9f

Please sign in to comment.