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

pr feat: question api #30

Merged
merged 26 commits into from
Jan 31, 2024
Merged

pr feat: question api #30

merged 26 commits into from
Jan 31, 2024

Conversation

toychip
Copy link
Member

@toychip toychip commented Jan 31, 2024

Issue number and Link

Summary

공통 댓글 구현, 공통 신고 구현
질문해요 게시글 작성, 게시글 단건 조회, 댓글 생성, 댓글 수정, 댓글 삭제(soft delete, Report 때문)

PR Type

  • Feature
  • Bugfix
  • Refactoring
  • Documentation
  • Other

Other Information

'�꿀팁공유해요'와 '질문해요'를 공유하는 페이지는 develop에 머지되어있는 재혁님이 만들어주신 코드를 활용해야하므로, 공유하는 페이지는 따로 이슈를 생성하여 작업하겠습니다.

Common Type

- feat : 새로운 기능 구현
- add : feat 이외의 부수적인 코드, 파일, 라이브러리 추가
- chore : 패키지 구조, 함수 및 변수명 변경 등의 작은 작업
- fix : 버그 및 오류 해결
- del : 불필요한 코드, 파일, 주석 삭제
- docs : 명세서 작성
- refactor : 코드 리팩토링
- merge : 서로 다른 브랜치 간의 코드 병합
- setting : 프로젝트 기초 세팅 관련 작업

branch

Feature/{이슈 번호 x, feat 순서}-{작업 내용}

ex)
Feature/3-home-api
Feature/4-home-crud

생성자가 없어 Null 값이 들어오는 오류 해결, 카테고리 자체로 받도록 수정
@toychip toychip linked an issue Jan 31, 2024 that may be closed by this pull request
7 tasks
@toychip toychip added ✨ Feature 새로운 기능 추가 🔀 PullRequest Branch 합병 임준형 labels Jan 31, 2024
@toychip toychip requested review from LEEJaeHyeok97 and removed request for LEEJaeHyeok97 January 31, 2024 06:00
Comment on lines 33 to 35
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "question_id")
private Question question;
Copy link
Contributor

Choose a reason for hiding this comment

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

한 개의 댓글 엔티티를 공유하기 때문에 null이 많아지는 문제가 향후 발생할 수도 있을것 같습니다.

Copy link
Member Author

Choose a reason for hiding this comment

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

공통 댓글 엔티티에서 직접 연관관계 매핑을 하는 것이 아닌, 이를 상속 받는 Question Entity에서 QuestionComment Entity 클래스로 이동하도록 수정하겠습니다.
단일테이블 전략이기 때문에 테이블 자체는 똑같지만 Comment를 유연하게 사용할 수 있겠네요!

@why-only-english why-only-english self-assigned this Jan 31, 2024
Copy link
Contributor

@why-only-english why-only-english left a comment

Choose a reason for hiding this comment

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

question api 큰 기능과 세부 내용, 그리고 댓글까지 작업하느라 고생 많으셨습니다 !

try {
return Category.valueOf(value.toUpperCase());
} catch (IllegalArgumentException e) {
throw new ApiException(ErrorType.CATEGORY_NOT_FOUNT);
Copy link
Contributor

Choose a reason for hiding this comment

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

CATEGORY_NOT_FOUNT 오타가 있네요. CATEGORY_NOT_FOUND로 수정하면 좋을 것 같습니다!

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 +22 to +32
private boolean deleted;

// 재활성화 - soft delete
public void activate() {
this.deleted = false;
}

// 비활성화 - soft delete
public void deactivate() {
this.deleted = true;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

soft delete 개념에서 enum 타입만 생각했었는데 deleted로 객체의 재활성화, 비활성화 상태를 관리하니 좋은 것 같네용

Comment on lines +46 to +49
public CommentEditor.CommentEditorBuilder toEditor() {
return CommentEditor.builder()
.comment(content);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

댓글을 편집하기 위해 빌더 패턴과 CommentEditor를 사용하니 매개변수 파악하는 가독성이 올라가는 것 같습니다.

Comment on lines +45 to +51
// 대댓글 생성
private Long registerCommentWithParent(final CommentCreateRequest request, final Question findQuestion,
final Comment parentComment) {
QuestionComment newQuestionComment = QuestionComment.withParentOf(request, parentComment, findQuestion);
commentService.register(newQuestionComment);
return newQuestionComment.getId();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

대댓글을 생성할 때 withParentOf를 사용하니 QuestionComment 클래스 내부에서 객체를 직접 생성할 수 있군요. 대댓글 기능 구현할 때 항상 어떤 식으로 할지 고민이었는데 참고해서 작업하겠습니다 !

Copy link
Member Author

Choose a reason for hiding this comment

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

객체를 생성하는 책임을 QuestionComment 도메인 자체에서 갖도록 하는 것이 맞다고 생각해서 이렇게 구현해봤습니다!

Comment on lines +35 to +41
public static QuestionImage of(final Question question, final String url) {
return QuestionImage.builder()
.url(url)
.question(question)
.build();
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

ImageResponse와 QuestionImage 객체를 생성할 때 from 메서드와 of 메서드를 사용하는 이유와 차이가 궁금합니다!!

Copy link
Member Author

Choose a reason for hiding this comment

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

디자인 패턴 중 static factory method 명명 규칙입니다.
보통 매개변수가 1개이면 from, 2개 이상이면 of를 사용합니다.

@@ -15,6 +15,13 @@ spring:
username: ${SPRING_DATASOURCE_USERNAME}
password: ${SPRING_DATASOURCE_PASSWORD}

jpa:
hibernate:
ddl-auto: validate
Copy link
Contributor

@why-only-english why-only-english Jan 31, 2024

Choose a reason for hiding this comment

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

ddl-auto 전략 중 update 대신 validate로 진행하는 이유가 있으신가요??

Copy link
Member Author

Choose a reason for hiding this comment

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

배포 환경에서 update로 두면 테이블의 변경 가능성이 있어 사용하면 안됩니다!
로컬 개발 환경일 때만 두고 사용하길 권장합니다~

Comment on lines +35 to +48
@Override
public List<QuestionComment> findActiveCommentsByQuestionId(final Long questionId) {
return jpaQueryFactory
.selectFrom(questionComment)
.where(
matchQuestionId(questionId),
getCommentActivate()
)
.orderBy(
questionComment.createdDate.asc(),
questionComment.parent.id.asc().nullsFirst()
)
.fetch();
}
Copy link
Contributor

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.

넵 댓글 삭제를 soft delete로 진행해야 Report에서 신고된 댓글을 볼 수 있다고 생각했습니다.
일반 사용자가 보기에 삭제된 댓글은 필수적으로 안보이게 해야한다고 생각했습니다.

Comment on lines +22 to +33
@Override
public Question findByIdFetchJoin(final Long questionPostId) {
Question findQuestion = jpaQueryFactory
.selectFrom(question)
.leftJoin(question.questionImages, questionImage)
.fetchJoin()
.where(question.id.eq(questionPostId))
.fetchOne();

return Optional.ofNullable(findQuestion)
.orElseThrow(() -> new ApiException(ErrorType.QUESTION_NOT_FOUND));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

fetch join을 사용하여 QuestionQuestionImage 사이의 N+1 문제를 해결할 수 있네요! 맨날 이론으로만 듣다가 실제 프로젝트에서 코드로 확인하니 더 이해가 됩니다. 역시 queryDSL 전문가~~ 👍👍

@toychip toychip merged commit 0492b88 into develop Jan 31, 2024
@toychip toychip deleted the Feat/3-Question-api branch October 17, 2024 07:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ Feature 새로운 기능 추가 🔀 PullRequest Branch 합병 임준형
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat: 질문해요 기능 구현
3 participants