Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4주차 세미나 기본과제 #5

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions week4/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
# Keep environment variables out of version control
.env
.DS_Store
.vscode
6 changes: 6 additions & 0 deletions week4/nodemon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"watch": ["src", ".env"],
"ext": "js,ts,json",
"ignore": ["src/**/*.spec.ts"],
"exec": "ts-node --transpile-only ./src/index.ts"
}
20 changes: 20 additions & 0 deletions week4/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "seminar4",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"dev": "nodemon",
"build": "tsc && node dist"
},
"devDependencies": {
"@types/express": "^4.17.14",
"@types/node": "^18.11.9",
"nodemon": "^2.0.20"
},
"dependencies": {
"@prisma/client": "^4.5.0",
"express": "^4.18.2",
"prisma": "^4.5.0"
}
}
15 changes: 15 additions & 0 deletions week4/prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

model User {
id Int @unique @default(autoincrement())
userName String
age Int?
email String? @db.VarChar(400)
}
1 change: 1 addition & 0 deletions week4/src/controller/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as userController } from "./userController";
65 changes: 65 additions & 0 deletions week4/src/controller/userController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Request, Response } from "express";
import { userService } from "../service";

//* 유저 생성 (추후 회원가입)
const createUser = async ( req: Request, res: Response ) => {
const { userName, email, age } = req.body; // req.body에 필드가 많은 경우에 대비하여 비구조화 할당

if (!userName || !email || !age) {
return res.status(400).json({ status: 400, message: "유저 생성 실패" });
}

const data = await userService.createUser(userName, email, age); // 컨트롤러의 역할을 분명히 하기 위해 DB와의 통신 내용은 적지 X.

if (!data) {
return res.status(400).json({ status: 400, message: "유저 생성 실패" });
}
return res.status(200).json({ status: 200, message: "유저 조회 성공", data });
};

//* 유저 전체 조회
const getAllUser = async ( req: Request, res: Response ) => {
const data = await userService.getAllUser();
return res.status(200).json({ status: 200, message: "유저 전체 조회 성공", data });
};

//* 유저 정보 업데이트
const updateUser = async ( req: Request, res: Response ) => {
const { name } = req.body;
const { userId } = req.params;

if (!name) return res.status(400).json({ status: 400, message: "유저 업데이트 실패!"});

const updatedUser = await userService.updateUser(+userId, name); // path parameter가 되면 string이 되어버리니까 + 써주기
return res.status(200).json({ status: 200, message: "유저 업데이트 성공", updatedUser});
};

//* 유저 삭제
const deleteUser = async ( req: Request, res: Response ) => {
const { userId } = req.params;

await userService.deleteUser(+userId);
return res.status(200).json({ status: 200, message: "유저 삭제 성공" });
};

const getUserById = async (req: Request, res: Response) => {
const { userId } = req.params;

const data = await userService.getUserById(+userId); // + : String -> Number (Number()와 동일)

if (!data) {
return res.status(404).json({ status: 404, message: "NOT_FOUND" });
}

return res.status(200).json({ status: 200, message: "유저 조회 성공", data });
};

const userController = {
createUser,
getAllUser,
updateUser,
deleteUser,
getUserById,
};

export default userController;
24 changes: 24 additions & 0 deletions week4/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import express, { NextFunction, Request, Response } from "express";
import router from "./router";

const app = express(); // express 객체 받아옴
const PORT = 3000; // 사용할 port를 3000번으로 설정

app.use(express.json()); // express 에서 request body를 json 으로 받아오겠다.

app.use("/api", router); // use -> 모든 요청
// localhost:8000/api -> api 폴더
// localhost:8000/api/user -> user.ts

//* HTTP method - GET
app.get("/", (req: Request, res: Response, next: NextFunction) => {
res.send("마! 이게 서버다!!!!!!!!!!!!!!!!!!!!");
});

app.listen(PORT, () => {
console.log(`
#############################################
🛡️ Server listening on port: ${PORT} 🛡️
#############################################
`);
}); // 8000 번 포트에서 서버를 실행하겠다!
8 changes: 8 additions & 0 deletions week4/src/router/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Router } from "express";
import userRouter from "./userRouter";

const router: Router = Router();

router.use("/user", userRouter);

export default router;
20 changes: 20 additions & 0 deletions week4/src/router/userRouter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Router } from "express";
import { userController } from "../controller";

const router: Router = Router();

router.get("/:userId", userController.getUserById);

// 유저 생성 - POST api/user
router.post('/', userController.createUser);

// 전체 유저 조회 - GET api/user
router.get('/', userController.getAllUser);

// 유저 정보 업데이트 - PATCH api/user/:userId
router.patch('/:userId', userController.updateUser);

// 유저 삭제 - DELETE api/user/:userId
router.delete('/:userId', userController.deleteUser);

export default router;
1 change: 1 addition & 0 deletions week4/src/service/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as userService } from "./userService";
63 changes: 63 additions & 0 deletions week4/src/service/userService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();

// 유저 생성
const createUser = async (name: string, email: string, age: number) => {
const data = await prisma.user.create({ // prisma를 이용해 user table에 create
data: {
userName: name, // DB에는 name이라는 필드가 없지만, 이런식으로는 가능(스키마에 선언된 필드 userName에는 controller에서 name으로 받은 것을 넣어주라~)
age,
email,
}
});

return data;
};

// 유저 전체 조회
const getAllUser = async () => {
const data = await prisma.user.findMany();
return data;
};

// 유저 정보 업데이트
const updateUser = async (userId: number, name: string) => {
const data = await prisma.user.update({
where: { // 어디를 (??)
id: userId
},
data: { // 어떻게 바꿀건지 (??맞나..)
userName: name
}
})
};

// 유저 삭제
const deleteUser = async (userId: number) => {
await prisma.user.delete({
where: {
id: userId,
},
});
};

//* userId로 유저 조회
const getUserById = async (userId: number) => {
const user = await prisma.user.findUnique({ // id는 PK -> unique
where: {
id: userId, // where : 일종의 필터. 조건. id가 userId인 경우만 조회
},
});

return user;
};

const userService = {
createUser,
getAllUser,
updateUser,
deleteUser,
getUserById,
};

export default userService;
28 changes: 28 additions & 0 deletions week4/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"compilerOptions": {
"target": "es6", //? 어떤 버전으로 컴파일
"allowSyntheticDefaultImports": true, //? default export가 없는 모듈에서 default imports를 허용
"experimentalDecorators": true, //? decorator 실험적 허용
"emitDecoratorMetadata": true, //? 데코레이터가 있는 선언에 대해 특정 타입의 메타 데이터를 내보내는 실험적인 지원
"skipLibCheck": true, //? 정의 파일 타입 체크 여부
"moduleResolution": "node", //? commonJS -> node 에서 동작
"module": "commonjs", //? import 문법
"strict": true, //? 타입 검사 엄격하게
"pretty": true, //? error 메시지 예쁘게
"sourceMap": true, //? 소스맵 파일 생성 -> .ts가 .js 파일로 트랜스 시 .js.map 생성
"outDir": "./dist", //? 트랜스 파일 (.js) 저장 경로
"allowJs": true, //? js 파일 ts에서 import 허용
"esModuleInterop": true, //? ES6 모듈 사양을 준수하여 CommonJS 모듈을 가져올 수 있게 허용
"typeRoots": [
"./src/types/express.d.ts", //? 타입(*.d.ts)파일을 가져올 디렉토리 설정
"./node_modules/@types" //? 설정 안할시 기본적으로 ./node_modules/@types
]
},
"include": [
"./src/**/*" //? build 시 포함
],
"exclude": [
"node_modules", //? build 시 제외
"tests"
]
}
Loading