[내일배움캠프] 2월 9일 목요일 TIL 회고록
오늘 한 것 : 내가 맡은 부분 (댓글) CRUD 기능 구현 (실행은 안해봄, 오류는 없었음)
저번에 했던 프로젝트를 보면서 기능을 구현했다.
ResponseDto 부분을 만들때 불변객체로 만들지 않았었다.
private Long id
이렇게 만들면 불변객체가 아니고
private final Long id
이렇게 final을 붙여야 불변객체이다.
팀원분이 깃허브 PR하고 코드리뷰를 하는데 지적을 받았어서 나도 바로 구글링해보고 ResponseDto 객체들을 전부 불변객체로 만들었다.
다음부터는 꼭 까먹지않고 불변객체로 만들어야겠다!
참고하면 좋은 블로그 : https://velog.io/@conatuseus/Java-Immutable-Object%EB%B6%88%EB%B3%80%EA%B0%9D%EC%B2%B4
[Java] Immutable Object(불변객체)
면접에서 "자바에서 불변객체에 대해 설명해주세요.."라는 질문을 받았다.속으로 'final만 붙이면 불변객체 아닌가?'라는 생각을 했지만 불변객체에 대해 공부하지 않아 모른다고 했다...그래서
velog.io
댓글 기능을 구현하다가 문득 고민이 들었다.
우리가 만드는 프로젝트는 게시판이 두개고 하나는 잡담 게시판, 하나는 질문 게시판인데 이 두 게시판에 대한 댓글을 만들때 기능 구현을 각각 해야할지 고민이었다. 말로 하기 힘들어 코드로 보여주자면..
질문 게시글 답변 작성 기능이다.
// 질문게시글 답변 작성
@PostMapping("/api/comments")
public ResponseEntity<String> createQuestionComment(
@RequestParam("question-board-id") Long boardId,
@RequestBody
CommentRequest requestDto, @AuthenticationPrincipal UserDetailsImpl userDetails) {
commentService.createQuestionComment(boardId, requestDto, userDetails.getUser());
return new ResponseEntity<>("답변 작성 완료!", HttpStatus.CREATED);
}
잡당 게시글 댓글 작성 기능이다.
잘 보면 PostMapping에 api 주소, 메서드 이름만 다르지 나머지는 전부 동일하다.
// 잡담게시글 댓글 작성
@PostMapping("/api/comments")
public ResponseEntity<String> createCommunityComment(
@RequestParam("community-board-id") Long boardId,
@RequestBody CommentRequest request, @AuthenticationPrincipal UserDetailsImpl userDetails) {
commentService.createCommunityComment(boardId, request, userDetails.getUser());
return new ResponseEntity<>("잡담 댓글 작성 완료!", HttpStatus.CREATED);
}
Service에서도 보면 동일하다.
질문 게시글 답변 작성 기능이다.
// 질문게시글 답변 작성
@Override
@Transactional
public void createQuestionComment(Long boardId, CommentRequest requestDto,
User user) {
// 게시물이 있는지 확인
// Board board = boardService.getBoard(boardId);
// 댓글 생성
Comment comment = new Comment(user, requestDto);
commentRepository.save(comment);
new CommentResponse(comment);
}
잡담 게시글 댓글 작성 기능이다.
이름만 다르지 코드도 같고 기능도 같다.
// 잡담게시글 댓글 작성
@Override
@Transactional
public void createCommunityComment(Long boardId, CommentRequest request, User user) {
// 게시글이 있는지 확인
// Board board = boardService.getBoard(boardId);
// 게시글이 있으면 댓글 작성
Comment comment = new Comment(user, request);
commentRepository.save(comment);
new CommentResponse(comment);
}
그래서 이걸 그냥 하나로 통일해서 하려고 생각했는데 나중에 기능을 추가하면 서로 출력해야 하는 것들이 달라질 것 같아서 통일하지 않았다...
이건 나중에 생각해봐야겠다.
기능 구현을 한 후 깃허브에 PR 한 후 팀장님한테 코드 리뷰를 받았다. 되게 떨렸다.
조언 사항은
첫번째는 질문, 답변 댓글을 삭제할 때 게시판의 id를 받았는데 필요없다는 말을 들었다.
그래서 바로 수정했다.
이제 삭제할 때 boardid를 받지 않고 commentid만 받도록 만들었다.
// 질문게시글 답변 삭제
@DeleteMapping("/api/comments")
public ResponseEntity<String> deleteQuestionComment(
@RequestParam("question-comment-id") Long commentId,
@AuthenticationPrincipal UserDetailsImpl userDetails) {
commentService.deleteQuestionComment(commentId, userDetails.getUser());
return new ResponseEntity<>("답변 삭제 완료!", HttpStatus.OK);
}
두번째는 좋아요 기능 부분에서 조언을 받았다.
지금 내가 만든 좋아요 기능은 컨트롤러 단에서도 예외를 출력해주고 서비스 단에서도 예외를 출력해준다.
그래서 굳이 컨트롤러단에 예외처리를 만들지 않아도 된다고 조언을 받았다.
그래서 if문을 아예 지우고 문제 없을때의 응답만 뱉어주고 리턴시켰다.
야매로 만든거라 기능이 잘 될지는 모르겠다..
// 좋아요 추가
@PostMapping("{commentId}/likes")
public ResponseEntity addLike(@PathVariable Long commentId, @AuthenticationPrincipal
UserDetailsImpl userDetails) {
commentLikeService.addLike(commentId, userDetails.getUser());
return new ResponseEntity<>("좋아요!", HttpStatus.OK);
}
세번째는 Comment 엔티티단에서 조언을 들었다.
좋아요 기능을 만들떄 commentLikes 객체를 만들어 좋아요 추가 기능이 post 되면 +1 ,좋아요 취소 기능이 post되면 -1을 했는데
엔티티 필드에 카운트를 넣지 말고 DB에서 CountBy를 활용해서 responseDto에만 값을 넣어주라고 하셨다.
내가 생각해도 엔티티 값이 변하는건 별로 좋지 못한 것 같았다..
그래서 좋아요 기능 레포지토리에 countByCommentId를 만들었다.
서비스단에서 구현은 하직 하지 못했다.. 내일 해봐야할 것 같다.
int countByCommentId(Long commentId);
네번째 조언은 서비스에서 checkUser 메소드 기능에 대해 조언을 들었다.
checkUser 메소드를 만들고 작성자와 현재 유저가 같은지, 어드민인지 확인하는 기능을 구현했는데
어드민은 따로 어드민 서비에서 만든다고 하셔서 user.getUserRole() != UserRole.ADMIN 부분은 빼도 된다고 하셔서 바로 뺐다.,
훨씬 보기 좋아졌다. ㅋㅋㅋ
// 작성자와 현재 유저가 같은지 확인하는 기능
private void checkUser(User user, Comment comment) {
if (comment.getUsername() != user.getNickName()) {
throw new IllegalStateException("댓글 작성자가 아닙니다.");
}
}
조언을 다 들은 후 조언받은 코드를 수정 후 오타 및 놓친 부분들을 수정했다.
내일 또 코드 리뷰를 받고 하나하나씩 수정해야겠다.