블로그 이미지

ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 대댓글 기능 구현하기
    Diary/우아한테크코스 2022. 10. 4. 22:06

    속닥속닥 프로젝트는 댓글 기능이 존재하는 상황이었다. 그런데 운영중 사용자들의 피드백으로 대댓글 기능을 도입해달라는 피드백이 많았고, 우리 팀 또한 대댓글을 도입하면 재미있을 거라고 생각해 기능 개발을 하게 되었다!

    요구 사항은 다음과 같다.

    • 댓글에 대댓글을 작성할 수 있다.
    • 댓글이 삭제 되더라도 대댓글은 남아 있어야 한다.
    • 댓글이 삭제된 상태에서, 그 댓글에 달린 대댓글이 모두 삭제되면 댓글 또한 완전히 삭제되어야 한다.
    • 익명으로 작성하는 댓글의 경우 임의의 닉네임(ex: 짜증나는 리액트)으로 보여주고, 한 번 댓글을 작성해 익명 닉네임을 할당 받은 경우 한 게시글에서는 같은 익명 닉네임을 사용하게 되는데, 이를 대댓글에도 적용한다.

    먼저, 대댓글 객체 설계에 대한 고민부터 시작했다.

    댓글 객체의 필드에 parent id를 추가하고 self join을 해 대댓글을 불러오도록 하는 방법과 대댓글 객체를 분리하여 구현하는 방법이 있었다.

    전자의 방법은 현재 대댓글의 최대 depth는 1이지만, 다음에 depth를 추가하고 싶다면 약간의 수정만으로 구현이 가능해 변경에 용이한 설계라고 생각이 되었다.

    하지만, 댓글 테이블 자체가 비대해져 쿼리를 수행할 때 성능이 느려진다는 단점이 있었고, 대댓글 자체를 도메인으로 바라볼 수 있기 때문에 도메인을 분리해야 한다는 생각이 들기도 했다. 후자의 방법은 도메인을 분리함으로써 더 객체 지향적인 설계를 할 수 있다는 생각이 들었고, 한 테이블에 들어가는 데이터 수도 간소화되어 쿼리의 성능이 늘어날 것이라 생각했다. 단점으로는 대댓글의 depth에 대한 추후 변경이 있다면 또 다른 객체를 생성해 같은 로직을 반복해야 하는 문제가 있어 확장성이 떨어진다는 문제가 있었다.

    이 두 가지 방법을 고민하다 객체지향 설계를 하는 이유는 변경에 용이하게 하기 위함이라고 생각해 후자의 방법은 확장성이 떨어져 전자의 방법을 선택하게 되었다.

    1. postId를 기준으로 모든 댓글, 대댓글들을 모아온다.
    2. parent가 없는 경우 -> 댓글
    3. parent가 있으면 → 대댓글
    4. parent가 있는데 parent 데이터가 존재하는 경우 -> depth 예외 발생

    comment 클래스에 softRemoved 필드를 추가해 대댓글 있는 경우의 댓글 삭제는 이 값을 true로 바꾸어 준다.

    댓글 삭제에서, 대댓글이 없으면 그냥 delete 한다.

    대댓글 삭제일 경우, 그냥 delete 한다. -> 부모인 댓글의 children list가 empty이고 softRemoved가 true이면 해당 댓글을 delete 한다.

     

    대댓글을 삭제하고, 댓글의 대댓글이 전부 삭제되었고 댓글이 softRemoved 상태인 경우에 댓글도 삭제를 해주어야 하는데, 같은 transaction 안에서 이루어지는 일이라 댓글의 children의 수를 검사할 때 비어있지 않은 것으로 나온다.

    해결 -> 대댓글 삭제 전에, parent 도메인의 children list에서 reply인 child 하나를 지우는 객체단의 메서드를 호출한다.

    댓글

Designed by Tistory.