후발대 강의 복습
실습
후발대 좋아요 API query 복습
후발대 노드숙련 남은 API 해보기 - https://github.com/jyh7a/week_1_assignment_gittest
선발대 DB 공부 - db query 많이 사용해보기(문제풀기)
공부
Failover 와 Failback을 알아보기
PaaS 알아보기
인덱스 시그니처(Index Signature) 알아보기 - https://developer-talk.tistory.com/297
정예반 노션읽고 공부하기 - https://teamsparta.notion.site/Node-js-0f4e60159f804788b806bdc322ed5ff3
JS / DEEP DIVE 공부
TS / 핸드북 공부 - https://typescript-kr.github.io/pages/tutorials/ts-for-the-new-programmer.html
TS / 장기효 핸드북 공부 - https://joshua1988.github.io/ts/intro.html
SQL 강의 - https://teamsparta.notion.site/SQL-835771d23a4c4045a6aa1fcc4ac8188a
CORS개념 - https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-CORS-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95-%F0%9F%91%8F
Promise 알아보기
강의
이승윤튜터님 노드입 문,숙련 - https://www.youtube.com/@happiestcoconut/playlists
백엔드 맛보기 - https://www.youtube.com/playlist?list=PLSK4WsJ8JS4cQ-niGNum4bkK_THHOizTs
Node.js Websocket 이론 - https://www.youtube.com/watch?v=82LB1jI_Nxw
소켓 send, emit 메서드 차이 - https://www.youtube.com/watch?v=JYNlZcKjWwk
타입스크립트 - https://www.youtube.com/playlist?list=PLJf6aFJoJtbUXW6T4lPUk7C66yEneX7MN
타입스크립트로 블록체인 만들기 - https://nomadcoders.co/typescript-for-beginners
줌 클론코딩 - https://nomadcoders.co/noom/lobby?utm_source=free_course&utm_campaign=noom&utm_medium=site
알고리즘
스파르타 알고리즘 풀기 / 2023/01/20 - https://school.programmers.co.kr/learn/courses/30/lessons/67256
스파르타 알고리즘 풀기 / 2023/01/19 - https://school.programmers.co.kr/learn/courses/30/lessons/131705
스파르타 알고리즘 풀기 / 2023/01/18 - https://school.programmers.co.kr/learn/courses/30/lessons/135808
스파르타 알고리즘 풀기 / 2023/01/17 - https://school.programmers.co.kr/learn/courses/30/lessons/134240
스파르타 알고리즘 풀기 / 2023/01/16 - https://school.programmers.co.kr/learn/courses/30/lessons/12982
사이트
- Node.js docs - https://teamsparta.notion.site/Node-js-4-docs-f467b6a53c9d42cb9ed65a21a20cbc84
- Spring docs - https://teamsparta.notion.site/Spring-4-docs-90ed70fceeec43559b042781feb9e0f2
- CORS개념 - https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-CORS-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95-%F0%9F%91%8F
오늘의 체크리스트
후발대 노드숙련 남은 API 해보기
- 댓글 작성 API
async function createComments(req, res) {
try {
const postId = parseInt(req.params.postId, 10);
const { id: userId } = res.locals.user;
const { comment: content } = req.body;
if (Object.keys(req.body).length <= 0) {
return res
.status(412)
.send({ errorMessage: "데이터 형식이 올바르지 않습니다." });
}
const post = await Post.findByPk(postId);
if (!post) {
return res.status(400).send({ errorMessage: "게시글이 없습니다" });
}
await Comment.create({ userId, postId, content });
res.status(201).send({ message: "댓글을 작성하였습니다." });
} catch (error) {
console.error(error);
res.status(500).send({ errorMessage: "댓글 작성에 실패하였습니다." });
}
}
- 댓글 조회 API
async function getComments(req, res) {
try {
const postId = parseInt(req.params.postId, 10);
const [comments, metadata] = await sequelize.query(`
select
c.id,
c.userId,
u.nickname,
c.content,
c.createdAt,
c.updatedAt
from
Comments as c
left join Users as u on c.userId = u.id
where
c.postId = ${postId};
`);
res.status(200).send({ data: comments });
} catch (err) {
console.error('Error: ', err.message);
res.status(400).send({ errorMessage: "댓글 조회에 실패하였습니다." });
}
}
쿼리문을 mysql-client에서 사용했을때는 정확하게 나왔다.
여태 작성하던 쿼리문보다 길어진 쿼리를 작성하면서 alias의 필요성을 조금 느꼈다.
테이블을 쓰고 as 를 입력하지 않고 alias를 사용해도 사용이 가능하지만 아직은 초보이니
명시적으로 as 를 붙이기로 했다.
Comments c ===== 가능
Comments as c ===== 가능
const { Sequelize } = require('../models')
Sequelize.query()를 사용해서 넣어주려니 캐치에 걸린다.
에러메세지를 읽어보니 Sequelize.query이라는 펑션을 찾을 수 없다는 것 같다.
저번에 정영훈 튜터님이 쓰는걸 본적이 있어서 영훈튜터님 깃과 녹화해둔 영상을 돌려보던도중
Sequelize를 sequelize로 대문자가 아닌 소문자를 사용하였다.
const { sequelize } = require('../models') 를 불러와서 사용하니 해결됐다.
그리곤 응답한 데이터를 보니 자꾸 같은 데이터 배열이 두개가 들어온다.
구글링을 해봤다.
// const [results, metadata] = await sequelize.query("UPDATE users SET y = 42 WHERE x = 12");
query()함수는 2개의 데이터를 반환한다.
https://pjt3591oo.github.io/sequelizejs_translate/build/html/CoreConcepts/RawQueries.html
https://sequelize.org/docs/v6/core-concepts/raw-queries/
- 댓글 수정 API
async function updateCommnets(req, res) {
try {
const commentId = parseInt(req.params.commentId, 10);
const { id: userId } = res.locals.user;
const { comment: content } = req.body;
if (Object.keys(content).length < 1) {
return res.status(412).send({ errorMessage: "데이터 형식이 올바르지 않습니다." });
}
try {
const [comment] = await Comment.update(
{ content },
{ where: { id: commentId, userId } }
);
if (!comment) {
return res.status(400).send({ errorMessage: "댓글이 존재하지 않습니다." });
}
res.status(200).send({ message: "댓글을 수정하였습니다." });
} catch (error) {
console.error('Error: ', error.message);
res.status(400).send({ errorMessage: "댓글 수정이 정상적으로 처리되지 않았습니다" });
}
} catch (error) {
console.error('Error: ', error.message);
res.status(400).send({ errorMessage: "댓글 수정에 실패하였습니다." });
}
}
sequelize.update() 의 리턴값이 못찾으면 [0], 찾으면 [1]로 반환된다.
const [comment] = await Comment.update();
배열안의 값을 변수에 할당해서 예외 처리를 해주었다.
if(!comment){}
- 댓글 삭제 API
async function deleteComments(req, res) {
try {
const commentId = +req.params.commentId;
const { id: userId } = res.locals.user;
try {
const destroyComment = await Comment.destroy({ where: { id: commentId, userId } });
if (destroyComment < 1) {
return res.status(404).send({ errorMessage: "댓글이 존재하지 않습니다." });
}
res.status(200).send({ message: "댓글을 삭제하였습니다." });
} catch (error) {
console.error('Error: ', error.message);
res.status(400).send({ errorMessage: "댓글 삭제가 정상적으로 처리되지 않았습니다." });
}
} catch (error) {
console.error('Error: ', error.message);
res.status(400).send({ errorMessage: "댓글 삭제에 실패하였습니다." });
}
}
후발대 좋아요 API query 복습
SELECT p.*, u.nickname, COALESCE(lc.cnt, lc.cnt, 0) AS `likes`
FROM Posts p
LEFT JOIN (
SELECT p.id, COUNT(p.id) as cnt
FROM Posts p
INNER JOIN Likes l ON p.id = l.postId
GROUP BY p.id
) AS lc
ON p.id = lc.id
LEFT JOIN Users u
ON p.userId = u.id;
서브쿼리, COALESCE 에 대하여 복습을 해봤다.