Skip to content
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

feat: 응원톡 삭제, 갯수 카운팅 및 랜덤으로 뽑아오기 API 작성 #217

Merged
merged 7 commits into from
Jan 29, 2023

Conversation

sanbonai06
Copy link
Member

@sanbonai06 sanbonai06 commented Jan 29, 2023

개요

작업사항

  • 응원톡 관련 여러가지 API들을 작성했습니다.
  • 응원톡 관련 뷰들이 나와있지가 않아서 티켓 프로젝트 22th를 보고 작성했습니다. 티켓 프로젝트 22 관련 컨트롤러
  • 삭제 기능은 soft-delete로 구현했습니다. 따라서 ACTIVE / INACTIVE로 나눴고 ACTIVE를 검사하는 로직들을 레포지토리에 추가해줬습니다.
  • 또한 삭제기능은 어드민 기능으로 알고 있어서 권한 검사도 추가했습니다.
  • 삭제 API의 반환값은 void입니다.
  • 갯수 카운팅 API는 왜있는지는 모르겠지만 일단 추가했습니다.
  • 랜덤으로 뽑기는 저번 프로젝트에서는 쿼리파라미터로 갯수도 받아서 몇개를 가져올건지도 했던데 아직 확실치 않아 일단 단건 조회로 구현했습니다.
  • Spring Data JPA나 QueryDsl은 랜덤 조회가 따로 없고 보통 쿼리로 구현한다했지만 레퍼런스를 뒤져본 결과 좋은 방법을 하나 발견해서 사용했습니다.
@Override
    public Comment queryRandomComment(Long eventId, Long countComment) {
        SecureRandom secureRandom = new SecureRandom();
        int idx = (int) (secureRandom.nextFloat(1) * countComment);

        PageRequest pageRequest = PageRequest.of(idx, 1);
        List<Comment> comments =
                queryFactory
                        .selectFrom(comment)
                        .where(eventIdEq(eventId), comment.commentStatus.eq(CommentStatus.ACTIVE))
                        .offset(pageRequest.getOffset())
                        .limit(1)
                        .fetch();

        JPAQuery<Long> countQuery =
                queryFactory
                        .select(comment.count())
                        .from(comment)
                        .where(eventIdEq(eventId), comment.commentStatus.eq(CommentStatus.ACTIVE));

        Page<Comment> commentOfPage =
                PageableExecutionUtils.getPage(comments, pageRequest, countQuery::fetchOne);

        if (commentOfPage.hasContent()) {
            return commentOfPage.getContent().get(0);
        }
        throw RetrieveRandomCommentNotFoundException.EXCEPTION;
    }
  • 각 한 개의 레코드를 가지는 페이지로 사이즈를 정한 뒤 랜덤으로 페이지 번호를 반환받아 고르는 방식을 사용했습니다.
  • 마지막 에러 부분은 정확한 워딩이 생각이 나지 않아서 일단 적어놓았는데 피드백 해주시면 고치겠습니다.

변경로직

  • 내용을 적어주세요.

@sanbonai06 sanbonai06 added the For: API [이슈 대상] 외부 API label Jan 29, 2023
@sanbonai06 sanbonai06 requested a review from ImNM as a code owner January 29, 2023 06:02
@sanbonai06 sanbonai06 self-assigned this Jan 29, 2023
Copy link
Member

@kim-wonjin kim-wonjin left a comment

Choose a reason for hiding this comment

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

페이지 랜덤 뽑기 아이디어 굿입니다 LGTM🌱


@Operation(summary = "응원글 개수를 카운팅합니다.")
@GetMapping(value = "/counts")
public RetrieveCommentCountResponse getCommentCounts(@PathVariable Long eventId) {
Copy link
Member

Choose a reason for hiding this comment

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

retrieve는 검색보다 회수의 의미가 더 강한거 같아용! 전에 개발사항들도 나중에 헷갈릴수도 있으니 한번 변경해놓으면 좋을거같아요

Copy link
Member Author

Choose a reason for hiding this comment

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

해당 컨벤션에 대해 오늘 회의 때 말해봅시당

Comment on lines +75 to +102
@Override
public Comment queryRandomComment(Long eventId, Long countComment) {
SecureRandom secureRandom = new SecureRandom();
int idx = (int) (secureRandom.nextFloat(1) * countComment);

PageRequest pageRequest = PageRequest.of(idx, 1);
List<Comment> comments =
queryFactory
.selectFrom(comment)
.where(eventIdEq(eventId), comment.commentStatus.eq(CommentStatus.ACTIVE))
.offset(pageRequest.getOffset())
.limit(1)
.fetch();

JPAQuery<Long> countQuery =
queryFactory
.select(comment.count())
.from(comment)
.where(eventIdEq(eventId), comment.commentStatus.eq(CommentStatus.ACTIVE));

Page<Comment> commentOfPage =
PageableExecutionUtils.getPage(comments, pageRequest, countQuery::fetchOne);

if (commentOfPage.hasContent()) {
return commentOfPage.getContent().get(0);
}
throw RetrieveRandomCommentNotFoundException.EXCEPTION;
}
Copy link
Member

Choose a reason for hiding this comment

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

페이지 랜덤 쿼리 참신한 아이디어 인것 같아요!🤭
마지막 exception 네이밍 관련해서는
특정 comment를 찾고자 한게 아니여서 notFound가 어울리는지 잘 모르겠어여 흠

Copy link
Member

@ImNM ImNM left a comment

Choose a reason for hiding this comment

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

굿굿
랜덤으로 하나 뽑아오는것 같은데
우리 보통막 5개정도 뽑지 않았었남?

Comment on lines 27 to 28
Long countComment = commentAdaptor.queryCommentCount(event.getId());
Comment comment = commentAdaptor.queryRandomComment(event.getId(), countComment);
Copy link
Member

Choose a reason for hiding this comment

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

commentAdaptor 로 묶어도?
좋을것같아요
commentAdaptor. queryRandomComment 에 countComment 인자를 없애도 될것같네유

Copy link
Member Author

Choose a reason for hiding this comment

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

좋은것 같습니다

Comment on lines +17 to +21
COMMENT_NOT_FOUND(NOT_FOUND, "Comment_404_1", "응원글을 찾을 수 없습니다."),
@ExplainError(value = "eventId 경로변수와 commentId가 맞지 않을 때 발생하는 에러입니다.")
COMMENT_NOT_MATCH_EVENT(BAD_REQUEST, "Comment_400_1", "응원글과 이벤트가 맞지 않습니다."),
COMMENT_ALREADY_DELETE(BAD_REQUEST, "Comment_400_2", "이미 삭제된 응원글입니다."),
RETRIEVE_RANDOM_COMMENT_NOT_FOUND(NOT_FOUND, "Comment_404_2", "랜덤 응원글을 찾을 수 없습니다.");
Copy link
Member

Choose a reason for hiding this comment

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

예시컨트롤러에 CommentErrorCode 노출 부탁드릴게유! 에러코드!

Copy link
Member Author

Choose a reason for hiding this comment

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

아맞다

Comment on lines +80 to +100
PageRequest pageRequest = PageRequest.of(idx, 1);
List<Comment> comments =
queryFactory
.selectFrom(comment)
.where(eventIdEq(eventId), comment.commentStatus.eq(CommentStatus.ACTIVE))
.offset(pageRequest.getOffset())
.limit(1)
.fetch();

JPAQuery<Long> countQuery =
queryFactory
.select(comment.count())
.from(comment)
.where(eventIdEq(eventId), comment.commentStatus.eq(CommentStatus.ACTIVE));

Page<Comment> commentOfPage =
PageableExecutionUtils.getPage(comments, pageRequest, countQuery::fetchOne);

if (commentOfPage.hasContent()) {
return commentOfPage.getContent().get(0);
}
Copy link
Member

Choose a reason for hiding this comment

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

랜덤하게 뽑는건 페이지네이션 쿼리가 필요할라나융

Copy link
Member

Choose a reason for hiding this comment

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

(카운트 쿼리) 리스트로도 충분할것같아서리

Copy link
Member Author

Choose a reason for hiding this comment

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

난수로 접근할 때 리스트로 접근하면 id와 같은 인덱스로 접근해야하는데 삭제된(INACTIVE)경우에는 없는 경우가 발생할 수 있음 / 리스트로 orderBy 랜덤때려서 상위 접근하면 쿼리 성능 떨어짐 => 페이지로 쪼갠 뒤 접근하면 위와 같은 경우가 다 해소된다고 하더라구요

Comment on lines 7 to 15

@DomainService
@RequiredArgsConstructor
public class CommentDomainService {

public void deleteComment(Comment comment, Long eventId) {
comment.checkEvent(eventId);
comment.delete();
}
Copy link
Member

Choose a reason for hiding this comment

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

트랜잭션 어노테이션 빠진듯!

Copy link
Member

Choose a reason for hiding this comment

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

그래도 여긴 있으면 usecase에서 실수할일은 없을것가탕유

Copy link
Member Author

Choose a reason for hiding this comment

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

추가하겠습니다

@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 222 Code Smells

15.5% 15.5% Coverage
0.0% 0.0% Duplication

@sanbonai06 sanbonai06 merged commit 59a988e into dev Jan 29, 2023
@sanbonai06 sanbonai06 deleted the feat/207-comment-admin branch January 29, 2023 12:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For: API [이슈 대상] 외부 API
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

🚀 [feature] [어드민]응원톡 삭제 및 갯수 카운팅 API 작성
3 participants