DB 이용하여 채널 생성하기
유효성 검사(express-validator)
if (!email) {
return res.status(400).json({
message: "이메일을 입력해주세요"
});
}
if (!title) {
return res.status(400).json({
message: "채널명을 입력해주세요."
});
}
이존의 이 코드들을 validator를 이용하여 유효성 검사로 빠지게 되었습니다. 유효성 검사 코드는 아래 코드로 대체하였습니다.
[body("email").notEmpty().withMessage("이메일을 입력해주세요")
.isEmail().withMessage("이메일 형식이 아닙니다."),
body("title").notEmpty().withMessage("채널명을 입력해주세요.")
.isString().withMessage("채널명은 문자열만 받습니다.")
]
만약에 이 유효성 검사가 맞지 않으면 에러를 내보내주어야 하는데 해당 코드는 아래와 같습니다.
const err = validationResult(req);
if (!err.isEmpty()) {
return res.status(400).json(err.array());
}
유저확인
채널 생성시 받는 데이터 값으로 body(title, description, email)을 받기로 했습니다.
하지만 이 값으로는 회원번호를 알 수 없기 때문에 유저 확인을 위한 sql을 작성하였고
data가 존재한다면 data의 id 값(= 회원번호)을 user_id에 저장하였습니다.
const select_user_sql = "select * from users where email = ?";
let user_id = "";
try {
const [[data]] = await conn.query(select_user_sql, email);
user_id = data.id;
} catch (err) {
return res.status(404).json({
message: "존재하지 않는 유저 입니다."
});
}
채널중복확인
동일 채널명을 갖지 않겠다는 조건을 걸었기 떄문에 채널중복 확인을 추가하였습니다.
const select_sql = "select * from channels where title = ?";
try {
const [[hasChannel]] = await conn.query(select_sql, title);
if (hasChannel) {
return res.status(409).json({
message: "이미 존재하는 채널명입니다."
});
}
} catch (err) {
return rew.status(400).end();
}
채널생성
유저 확인에서 가져온 user_id값을 이용하여 채널생성을 하였습니다.user_id값이 없는 경우에는 FK 오류가 발생하지만 위의 유저 확인 덕분에 해당 검사는 하지 않아도 될것같습니다.
const insert_sql =
"insert into channels (title, description, user_id) values (?,?,?)";
const insert_values = [title, description, user_id];
try {
await conn.query(insert_sql, insert_values);
res.status(201).json({
message: `${title} 채널을 응원합니다.`
});
} catch (err) {
return res.status(404).end();
}
이전 코드 정리
user와 마찬가지로 database 설정을 아직 하지 않아 Map 객체로 대체합니다.
DB 구성
// 변경 후 channel DB (23.12.17)
db = {
channelNum(key) : {
userId : '유저아이디',
channelTitle : '채널명',
description : '채널설명문'
}
}
// 기존 db
db = {
idx,
{
user : test1,
channels :[
{channelTitle : '테스트', description : '채널설명'}
]
}
}
기본 코드 작성
//변경후 코드 (23.12.17)
app
.route("/")
.post((req, res) => {
const channel = req.body;
res.status(201).json({
message: '채널생성 API'
});
})
// 변경 전 코드
app
.route("/channels/:user")
.post((req, res) => {
const { user } = req.params;
const data = req.body;
res.status(201).json({
message: '채널생성 API'
});
})
기존 코드에서는 router 관리를 하지 않아 URI 전부를 입력해 주어야 했었는데 server와 router를 분리함에 따라 channel의 공통 URI인 channels를 뺀 나머지 path를 입력하고. :user로 params 값을 받아왔었는데 해당 부분은 보안상의 이유로 일단 body 값으로 전달하기로 하였습니다.
Check 사항
1. data가 제대로 들어왔는가?
2. 이미 존재하는 채널명인가?
3. 기존유저인가 신규유저인가?
로 검사항목을 나눠봤습니다.
1. data가 제대로 들어왔는가?
// 변경후 코드
if (!channel || !channel.channelTitle) {
res.status(400).json({
message: "채널명을 입력해주세요"
});
return;
}
// 변경전 코드
if (!data ||! data.channelTitle) {
res.status(400).json({
message: "채널명을 입력해주세요"
});
return;
}
왜 data의 description은 확인하지 않는 건가요?
채널 설명은 일단 유효성 검사에서 배재했습니다. 작성하는 분들도 있고, 작성하고 싶지 않은 분도 있을 것이기 때문에 선택사항이라 판단했고 때문에 if문 조건에서 배재되었습니다.
postman 결과
2. 이미 존재하는 채널명인가?
let titleCheck = false;
db.forEach((value) => {
if (channel.channelTitle === value.channelTitle) {
titleCheck = true;
}
});
if (titleCheck) {
res.status(409).json({
message: "이미 존재하는 채널명입니다."
});
return;
}
// 변경전 코드
let titleCheck = false;
db.forEach((value) => {
for (let i = 0; i < value.channels.length; i++) {
if (value.channels.length > 0) {
if (data.channelTitle === value.channels[i].channelTitle) {
titleCheck = true;
}
}
}
});
if (titleCheck) {
res.status(409).json({
message: "이미 존재하는 채널명입니다."
});
return;
}
채널 중복을 막기 위해서 titleCheck를 통해 true값을 반환하는 게 존재한다면 409 상태코드와 이미 존재하는 채널명이라는 message 전달해 주었습니다.
409 상태코드는 "사용자의 요청이 서버의 상태와 충돌하여 응답하는 코드"인데요. 이미 db에 존재하는 타이틀명을 사용자가 똑같은 타이틀로 데이터를 요청하여 서버에서 충돌이 났다 생각하여 409 상태코드로 입력을 했습니다.
postman 결과
3. 기존 유저인가? 신규 유저인가?
// 변경후 코드
db.set(idx++, channel);
res.status(201).json({
message: `${db.get(idx - 1).userId}님 ${
db.get(idx - 1).channelTitle
} 채널을 응원합니다.`
});
// 변경전 코드
let userHas = false;
let userKey = "";
let msg = "";
db.forEach((value, key) => {
if (user === value.user) {
userHas = true;
userKey = key;
}
});
// 기존유저면 data를 channels에 추가하고
if (userHas) {
db.get(userKey).channels.push(data);
msg = `${db.get(userKey).user}님 ${
db.get(userKey).channels[db.get(userKey).channels.length - 1]
.channelTitle
} 채널을 응원합니다.`;
} else {
//신규유저면 user와 data를 모두 추가해 준다.
db.set(idx++, {
user: user,
channels: [data]
});
msg = `${db.get(idx - 1).user}님 ${
db.get(idx - 1).channels[db.get(idx - 1).channels.length - 1]
.channelTitle
} 채널을 응원합니다.`;
}
res.status(201).json({
message: msg
});
기존 유저의 경우에는 유저의 아이디 혹은 회원번호를 받아서 user가 존재한다면 user의 key값을 받아서 db.get(key)를 넣어주어야 하고, user가 없었을 경우에는 idx로 key값을 받아오게 작성을 했습니다. 또한 이미 유저가 존재하면 data를 channels에 push로 넣어주고 신규유저라면 channels에 바로 data가 입력이 되게 작성했습니다.
마지막으로 msg의 경우에는 key값을 받아오는 변수가 다르기 때문에 변수에 맞게 msg를 추가해 주었습니다.
(23.12.17) 변경 후 코드
db 변경에 따라서 따로 기존유저인지 아닌지 필요가 없어졌기 때문에 1,2 조건이 해결 됐다면 바로 데이터를 db에 담아주고 메시지를 띄우게 변경하였습니다.
postman 결과
'프로젝트 > 1.youtube-project' 카테고리의 다른 글
[실전]미니 프로젝트 - 개별 채널 "삭제" (0) | 2023.12.15 |
---|---|
[실전]미니 프로젝트 - 채널 개별 "조회" (0) | 2023.12.14 |
[실전]미니 프로젝트 - 로그인 (0) | 2023.12.14 |
[실전]미니 프로젝트 - 회원 개별 "탈퇴" (0) | 2023.12.14 |
[실전]미니 프로젝트 - 회원 개별 "조회" (0) | 2023.12.14 |