[황채원] Sprint 10#16
Hidden character warning
Conversation
Irelander
left a comment
There was a problem hiding this comment.
검증 로직 중복 제거 (joi/zod 도입 검토)하고 에러 처리를 더 세밀하게 (토큰 만료 vs 변조 구분) 하는걸 신경쓰면 더 견고한 백엔드 코드가 될 것 같습니다 :)
이번 스프린트도 고생하셨어요!
| const isLiked = userId | ||
| ? !!(await prisma.Like.findFirst({ | ||
| where: { articleId: id, userId }, | ||
| })) | ||
| : false; |
There was a problem hiding this comment.
article 조회 후 별도로 Like 조회를 하게 되면서 쿼리 2번이 발생해요! ( N+1의 문제라고 합니다. )
include에서 한 번에 가져오면 쿼리 1번으로 처리 가능하니 개선하면 좋아요!
| const data = { | ||
| id: article.id, | ||
| title: article.title, | ||
| content: article.content, | ||
| image: article.image.length ? article.image[0] : DEFAULT_ARTICLE_IMAGE, | ||
| createdAt: article.createdAt, | ||
| updatedAt: article.updatedAt, | ||
| userId: article.user.id, | ||
| nickname: article.user.nickname ?? "오류", | ||
| image: article.user.image || DEFAULT_PROFILE_IMAGE, | ||
| likeCount: article._count.Like, | ||
| isLiked, | ||
| }; |
There was a problem hiding this comment.
엇 image 속성이 중복되어서 더 나중에 선언된 유저 이미지로 사용되어질꺼에요, 이부분 확인이 필요할꺼 같네요 !
| export const updateComment = asyncHandler(async (req, res) => { | ||
| const { id } = req.params; | ||
| const { content } = req.body; | ||
|
|
||
| const exist = await prisma.comment.findUnique({ where: { id } }); | ||
| if (!exist) | ||
| return res.status(404).json({ message: "존재하지 않는 댓글입니다." }); | ||
|
|
||
| const updated = await prisma.comment.update({ | ||
| where: { id }, | ||
| data: { content }, | ||
| include: { | ||
| user: { select: { id: true, nickname: true, image: true } }, | ||
| }, | ||
| }); | ||
|
|
||
| res.json({ message: "댓글 수정 완료", comment: updated }); | ||
| }); |
There was a problem hiding this comment.
권한 검증이 없어서 누구나 수정할수 있을꺼 같아요 ㅎㅎ
추가로 findUnique로 존재하는지 검사후 업데이트하는데, update 쿼리를 날렸을때 존재하지 않는다면 업데이트 행이 0개라 존재하지 않는지 확인 가능해요! 따로 존재하는지 확인해서 업데이트 할 필요가 없습니다 !
| await prisma.$transaction([ | ||
| prisma.articleLike.create({ | ||
| data: { articleId: id, userId }, | ||
| }), | ||
| prisma.article.update({ | ||
| where: { id }, | ||
| data: { likeCount: { increment: 1 } }, | ||
| }), | ||
| ]); | ||
|
|
||
| res.status(201).json({ message: "게시글 좋아요 등록" }); | ||
| }); |
There was a problem hiding this comment.
schema.primsa에 Like모델로 정의도어 있는데 여긴 다른 모델로 처리되어 있어서 혼동이 있을꺼 같아요 ㅎㅎ 동일하게 사용되면 더 좋을꺼 같습니다.
| await prisma.$transaction([ | ||
| prisma.favorite.create({ | ||
| data: { productId: id, userId }, | ||
| }), | ||
| prisma.product.update({ | ||
| where: { id }, | ||
| data: { favoriteCount: { increment: 1 } }, | ||
| }), | ||
| ]); | ||
|
|
||
| res.status(201).json({ message: "상품 좋아요 등록" }); |
There was a problem hiding this comment.
한 사용자가 여러번 좋아요를 누를수 있기때문에 중복 좋아요 방지를 하는 코드가 들어가면 더 좋을꺼 같습니다 ㅎㅎ
| if (!authHeader) | ||
| return res.status(401).json({ message: "토큰이 필요합니다." }); | ||
|
|
||
| const token = authHeader.split(" ")[1]; |
There was a problem hiding this comment.
Bearer 토큰인지 검사하는건 중요합니다. ( 유형 ) Faketype token 이런 형태로 보내도 정상적으로 처리될 수 있으므로 검사해주는게 좋습니다 ㅎㅎ
| const decoded = jwt.verify(token, JWT_SECRET); | ||
| const user = await prisma.user.findUnique({ where: { id: decoded.id } }); |
There was a problem hiding this comment.
JWT의 장점중 하나가 JWT만 가지고 유저정보를 획득할수 있다는건데 DB에서 실제로 검사를 하는 단계가 들어가서 장점이 사라지게 됩니다 ! ㅎㅎ 이미 JWT에 유저정보가 있으니 불필요한 쿼리는 호출핮 ㅣ않도록 ㅎ ㅏ는게 좋을꺼 같습니다
| export const checkOwnership = (model) => { | ||
| return async (req, res, next) => { | ||
| const { id } = req.params; | ||
| const record = await prisma[model].findUnique({ where: { id } }); | ||
|
|
||
| if (!record) return res.status(404).json({ message: "존재하지 않습니다." }); | ||
| if (record.userId !== req.user.id) | ||
| return res.status(403).json({ message: "권한이 없습니다." }); | ||
|
|
||
| next(); | ||
| }; | ||
| }; |
There was a problem hiding this comment.
DB조회나 네트워크 요청과 같은곳엔 항상 try ~ catch를 해주는게 좋습니다
There was a problem hiding this comment.
title이 숫자나 객체면 .length가 undefined거나 에러 발생할 수 있어요.
추가로 JSON으로 들어오면 price는 string이에요. typeof price !== "number"로 체크하면 항상 실패할꺼 같습니다 ㅠ
요구사항
기본
공통
https://panda-market-api.vercel.app의 API를 사용한 코드를 본인의 백엔드 API 코드로 변경하세요.
백엔드 구현 요구사항
상품 등록
상품 상세
좋아요 기능
에러 처리
라우트 중복 제거
인증
상품 기능 인가
게시글 기능 인가
댓글 기능 인가
심화
인증
OAuth를 활용한 인증
(생략 가능) 자유게시판 게시물 등록
주요 변경사항
스크린샷
멘토에게