Skip to content

Comment: comment 모듈 추가 및 application, api 작성 #68

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 25 commits into
base: main
Choose a base branch
from

Conversation

seonghooni
Copy link

@seonghooni seonghooni commented May 3, 2025

Pull Request

Issues

Description

  • api, application, driven/rdb, driving/web 모듈 추가

    • comment 및 reply에 대한 domain, excepltion, readmodel 모듈을 작성했습니다.
    • comment 및 reply에 대한 port를 작성했습니다.
    • comment 및 reply에 대한 entity, persistence를 작성했습니다.
  • postgresql migration script를 작성했습니다.

  • basePackage 컨벤션에 맞게 리팩토링 진행했습니다.

How Has This Been Tested?

Comment, Reply에 대한 Create, Update, Delete API를 실행한 후,
Read API를 실행시킨 결과입니다.

image

Additional Notes

현재 작성한 댓글 조회 기능에서 댓글과 대댓글을 10개씩 가져오는데,
이 과정에서 N+1 비효율이 발생합니다.

게시물에 대한 댓글을 최대 10개, 또한 각각의 댓글에 대한 대댓글을 최대 10개 불러와야 하지만,
QueryDSL에서 제공하는 기본 구문으로는 이 코드를 최적화 할 수 없습니다.

nettee.comment.application.service.CommentQueryService의 함수입니다.

public List<CommentDetail> getCommentsByBoardId(Long boardId) {
        var comments = commentQueryRepositoryPort.findPageByBoardId(boardId, 0, 10);

        // comment별로 reply를 10개씩 가져옴
        **// 현재 N+1 이므로, 최대 11(1+10)개의 쿼리를 발생시킴**
        var result = comments.stream()
            .map(comment -> {
                var replies = replyQueryRepositoryPort.findPageByCommentId(comment.id(), 0, 10);

                return CommentDetail.builder()
                    .id(comment.id())
                    .content(comment.content())
                    .status(comment.status())
                    .createdAt(comment.createdAt())
                    .updatedAt(comment.updatedAt())
                    .replies(replies)
                    .build();
            }).collect(Collectors.toList());

        return result;
    }

위 코드를 NativeQuery를 써서 최적화를 할지
vs
11개의 쿼리는 N+1 문제일지라도 예측 가능한 범위 내에 있기 때문에 그대로 둘지

에 대한 고민은 해봐야 할 것 같습니다.

@merge-simpson merge-simpson added review: required Reviews are required type: feature 새로운 기능 또는 기능적 개선 A new feature or enhancement in: comment Issues in the comment module labels May 5, 2025
Comment on lines 33 to 35
project(":comment:application").projectDir = comment("application")
project(":comment:rdb-adapter").projectDir = comment("rdb")
project(":comment:webmvc-adapter").projectDir = comment("web-mvc")
Copy link
Member

@merge-simpson merge-simpson May 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❗️ "web-mvc" 폴더가 존재하지 않습니다.

단, 이것을 해결해도 다른 오류가 남아 있어 정상적으로 실행되지는 않습니다.
(자주 언급되고 있는 오류이므로 다른 리뷰보다 먼저 싱글 코멘트로 남기겠습니다.)

val comment = getDirectories("services", "comment")

// SERVICE/COMMENT
include(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

타 도메인과 중복되는 모듈명으로 부터 main-runner 모듈에서 yml 파일 import 부분에 트러블슈팅이 있었습니다!

하기와 같은 수정을 요청 드립니다.

  • 수정 예시
include(
    ":comment",
    ":comment:comment-api",
    ":comment:comment-api-domain",
    ":comment:comment-api-exception",
    ":comment:comment-api-readmodel",
    ":comment:comment-application",
    ":comment:comment-rdb-adapter",
    ":comment:comment-webmvc-adapter",
)

project(":comment").projectDir = comment("comment")
project(":comment:comment-api").projectDir = comment("api")
project(":comment:comment-api-domain").projectDir = comment("domain")
project(":comment:comment-api-exception").projectDir = comment("exception")
project(":comment:comment-api-readmodel").projectDir = comment("readmodel")
project(":comment:comment-application").projectDir = comment("application")
project(":comment:comment-rdb-adapter").projectDir = comment("rdb")
project(":comment:comment-webmvc-adapter").projectDir = comment("web-mvc")

Comment on lines 13 to 26
@Getter
@DynamicUpdate
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity(name = "comment")
public class ReplyEntity extends LongBaseTimeEntity {

@Id
private Long id;

private String content;

@Convert
private ReplyEntityStatus status;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

엔티티 관련한 문의사항이 있습니다!

  1. 접근제한자 private
  • Entity 필드의 접근 제한자는 멀티 모듈 환경에서 public으로 지정하기로 하였습니다.
  • 모듈이란 스코프 내에서 코딩이 이루어지기 때문에 private는 불필요 했습니다.
  • 테스트 코드를 짤 때 더 유연해집니다.
  1. @convert에 컨버터를 위한 클래스 지칭
  • Convert는 따로 해당 필드를 위한 컨버터 클래스를 지칭해야 하는 것으로 알고 있습니다. 혹시 이 작업은 누락일까요?
  • board 예시
@Getter
@DynamicUpdate
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity(name = "board")
public class BoardEntity extends LongBaseTimeEntity {
    public String title;
    public String content;

    @Convert(converter = BoardEntityStatusConverter.class)
    public BoardEntityStatus status;

    @Builder
    public BoardEntity(String title, String content, BoardEntityStatus status) {
        this.title = title;
        this.content = content;
        this.status = status;
    }
}
  1. builder 패턴을 적용하지 않은 이유가 있을까요?

@merge-simpson merge-simpson changed the title Comment - comment 모듈 추가 및 application, api 작성 Comment: comment 모듈 추가 및 application, api 작성 May 13, 2025
@merge-simpson merge-simpson added review: ing Reviews are in progress and taking time and removed review: required Reviews are required labels May 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: comment Issues in the comment module review: ing Reviews are in progress and taking time type: feature 새로운 기능 또는 기능적 개선 A new feature or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[SUB-ISSUE] Comment: 모듈별 베이스 패키지 구분 [MAIN] Comment, Reply Domain 구현
3 participants