TIL 230501_Layered architecture pattern 적용하기1
✅오늘 학습 Keyword 3계층 아키텍쳐 1. Controller : 요청, 응답처리 2. Service: 비즈니스로직이 수행되는 부분, 요구사항을 처리하는 중심 부분이기 떄문에 현업에서는 서비스코드가 비대해진다 3. Repos
veritas-crystal.tistory.com
**Layered architecture pattern 적용하기1
✅오늘 학습 Keyword
기존의 게시판 API에 3계층 아키텍처 패턴 적용하기
✅오늘 겪은 문제 및 해결
1.
아래와 같이 repo와 service를 작성하고 댓글을 불러오면, 댓글의 데이터 일부 반영되지 않는 문제
댓글의 데이터가 전부 출력되지 않는다.
const CommentsRepository = require ( '../repositories/comments.repository' );
class CommentsService {
commentsRepository = new CommentsRepository ();
createComment = async ( userId , postId , content ) => {
const commentData = await this . commentsRepository . createComment (
userId ,
postId ,
content
);
return commentData ;
};
findCommentById = async ( postId ) => {
const allcomments = await this . commentsRepository . findallCommentById (
postId
);
// //호출한 comments들을 가장 최신부터 정렬
// allcomments.sort((a, b) => {
// return b.createdAt - a.createdAt;
// });
return allcomments . map (( comment ) => {
console . log ( comment );
//이부분에서 에러가 났는데
return {
commentId : comment . commentId ,
UserId : comment . userId ,
PostId : comment . postId ,
comment : comment . content ,
createdAt : comment . createdAt ,
updatedAt : comment . updatedAt ,
};
});
};
}
module . exports = CommentsService ;
해결방법 : service 에서 repository에게 원하는 정보를 요청할때는, repo의 데이터 형식에 맞춰줘야 정상적으로 불러옴.
즉 우리가 repo에서 찾은 comments 모델의 값을 가져와야함.
comments 모델은 UserId, PostId, commentId, comment, createdAt, updatedAt 으로 구성되있기에 대소문자를 잘 구분해줘야함.
return {
commentId : comment . commentId ,
UserId : comment . UserId ,
PostId : comment . PostId ,
comment : comment . comment ,
createdAt : comment . createdAt ,
updatedAt : comment . updatedAt ,
};
});
};
}
module . exports = CommentsService ;
정상적으로 출력되는 것을 볼 수 있다!
2.
좋아요를 등록하는 부분에서 3계층을 어떻게 나눠야할지 정~~말 고민이 많았다..
기존 router에선 하나의 PUT 라우터 안에서 등록 & 조회 & 취소를 해결했기에 그 부분을 3계층으로 나누는데에 시간이 좀 걸렸다..특히 controller에서 조건, 즉 이미 좋아요가 있을시 like데이터를 삭제하는 부분에서 걸렸지만 아래와 같이 완성하였다.
const { urlencoded } = require ( 'express' );
const LikesService = require ( '../services/likes.service' );
class LikesController {
likesService = new LikesService ();
putLikes = async ( req , res , next ) => {
try {
const { postId } = req . params ;
const { userId } = res . locals . user ;
const existsLike = await this . likesService . findLike ( postId , userId );
if ( existsLike ) {
console . log ( existsLike );
await this . likesService . deleteLikes ( postId , userId );
return res . status ( 201 ). json ({
message : '좋아요를 취소했습니다.' ,
});
}
const createLike = await this . likesService . putLikes ( postId , userId );
res . status ( 201 ). json ({ message : '좋아요를 추가했습니다.' , createLike });
} catch ( err ) {
console . error ( err );
res . status ( 400 ). json ({ message : '게시글 좋아요에 실패하였습니다.' });
}
};
}
//---->
module . exports = LikesController ;
하지만 controller에 문제가 없어보이는데도 불구, 좋아요가 추가만 되고 destroy되지 않는 에러가 계속 발생했다.
해결방법: 이 문제는 예상외로 아주 간단하게 해결했는데, service 부분에 putLikes만 추가해놓고 findLike, delete를 추가하지 않았다...이 문제를 해결하면서 각 단계에서 쓰이는 함수는 반드시!! 단계마다 똑같이 구현해놔야한다는 것..
개념으로는 알고있는데도 적용하면서 빼먹게됐는데, 기계처럼 인지하고있어야겠다.
service를 아래와 같이 작성하고,
const LikesRepository = require ( '../repositories/likes.repository' );
class LikesService {
likesRepository = new LikesRepository ();
findLike = async ( postId , userId ) => {
const existsLike = await this . likesRepository . findLike ( postId , userId );
return existsLike ;
};
putLikes = async ( postId , userId ) => {
const createLike = await this . likesRepository . createLikes ( postId , userId );
return createLike ;
};
deleteLikes = async ( postId , userId ) => {
await this . likesRepository . deleteLikes ( postId , userId );
return ;
};
}
module . exports = LikesService ;
repository를 아래와 같이 작성해주니
const { Likes } = require ( '../models' );
class LikesRepository {
createLikes = async ( postId , userId ) => {
const likeData = await Likes . create ({
UserId : userId ,
PostId : postId ,
});
return likeData ;
};
findLike = async ( postId , userId ) => {
const existsLike = await Likes . findOne ({
where : { PostId : postId , UserId : userId },
});
return existsLike ;
};
deleteLikes = async ( postId , userId ) => {
await Likes . destroy ({
where : { PostId : postId , UserId : userId },
});
return ;
};
}
module . exports = LikesRepository ;
//여기서 답을 두개줄 수 있다
취소기능도 완료!
3.
1. C:\Users\cryst\OneDrive\바탕 화면\sparta\NODE JS\주특기주차\layered-architecture-pattern\node_modules\express\lib\router\route.js:211 throw new Error(msg); ^ Error: Route.post() requires a callback function but got a [object Undefined] 에러 ------->라우터 연결문제, 스펠링체크, 각 단계별 연결 체크
✅오늘 느낀점 및 계획
3계층 아키텍쳐 패턴이란것이 말그대로 한 단계를 3계층으로 나누는 개념에 많이 익숙해졌다.
페이지만 나눌뿐 결국은 한 작업을 수행하는 것이기 때문에 controller에선 service를, service에선 repo를 불러오는 flow를 이해하면 훨씬 쉬워진다. 1차에선 controller, service, repo순으로 작성했는데 그것보단 controller로 틀을 잡고 repo부터 작성하는 것이 service까지 완성하기에 수월했다. 명일 좋아요 조회기능과 보완해야할 부분을 진행할 예정.