Skip to content

[Week07] 죠죠 7주차 미션#23

Merged
yousung1020 merged 4 commits into
mainfrom
week07_jojo
May 18, 2026
Merged

[Week07] 죠죠 7주차 미션#23
yousung1020 merged 4 commits into
mainfrom
week07_jojo

Conversation

@ddo0122
Copy link
Copy Markdown
Contributor

@ddo0122 ddo0122 commented May 16, 2026

(필수) 내가 진행중인 미션 조회하기

image

(필수) 내가 생성한 리뷰들 조회하기

image

(필수) Request Body가 있는 API에 검증 어노테이션 붙혀 검증하기

@ddo0122 ddo0122 requested a review from yousung1020 May 16, 2026 14:12
@ddo0122 ddo0122 self-assigned this May 16, 2026
Copy link
Copy Markdown
Contributor

@yousung1020 yousung1020 left a comment

Choose a reason for hiding this comment

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

수고하셨습니다! 미션을 잘 수행하신 것 같습니다! 다음 미션에 피드백을 반영하여 주시면 더욱 좋을 것 같아요!

Comment on lines +38 to +51
public record Pagination<T>(
List<T> data,
Boolean hasNext,
String nextCursor,
Integer pageSize
) {}

// 페이지네이션 틀(Offset)
@Builder
public record OffsetPagination<T>(
List<T> data,
Integer pageNumber,
Integer pageSize
) {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

dto 이너클래스에 타입을 사용하는 이유과 모순점에 대해서 말씀드리고자 합니다! 이를 알아두어야 왜 이렇게 사용했고, 이렇게 쓰면 오히려 더 복잡하겠구나를 아는 것이 중요하다고 생각해요!

제네릭 타입 를 사용하는 이유는 DRY(Dont Repeat Yourself, 중복제거) 원칙 때문입니다! 프로젝트 규모가 커져 페이징 처리가 필요한 도메인이 점점 불어나게 됩니다! 그렇다는 것은 제네릭 를 사용하지 않으면 새로운 도메인이 생길 때마다 똑같은 구조의 페이징용 dto를 매번 만들어야 합니다!

하지만 여기에는 모순점도 존재합니다. 으로 모든 타입을 뚫어놨지만, 정작 해당 구조는 MissionResDTO 라는 특정 도메인 클래스 내부에 갇혀있다는 것입니다! 즉, 다른 도메인에서 해당 dto의 record 클래스를 사용하기 위해서는 MissionResDTO.Pagination<엔티티 타입> 으로 작성해야 합니다. 예를 들면 리뷰 도메인에서 미션 도메인의 dto를 import 해야 하는 상황이 발생하게 된다는 의미입니다!

결론적으로 제네릭 방식을 고수하고자 한다면 Pagination 자체를 특정 도메인 영역 밖으로 꺼내서 전역적인 패키지에 독립시키는 것이 좋아보입니다! 특정 도메인에서만 쓸거라면 가 아닌, 구체적인 타입을 명시하여 필드를 구성하는 것이 더욱 안전할 것 같습니다!

Comment on lines +21 to +27
List<Mission> findAvailableMissionsByLocation(String location);

Slice<Mission> findMissionsByStore_IdAndIdLessThanOrderByIdDesc(Long storeId, long idCursor, Pageable pageRequest);

Slice<Mission> findMissionsByStore_IdOrderByIdDesc(Long storeId, Pageable pageRequest);

Page<Mission> findAllByStore_Id(Long storeId, Pageable pageable);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

_Id 와 같은 패턴은 잘 쓰이지 않습니다! StoreId 와 같이 작성하는 것이 좋아보여요!

if (!userRepository.existsById(userId)) {
throw new UserException(UserErrorCode.USER_NOT_FOUND);
//가게 내 미션들 조회
public MissionResDTO.Pagination<MissionResDTO.MissionInfo> getMissions(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

첫 페이지와 다음 페이지를 구분하기 위한 조건 분기가 서비스 계층에 그대로 있어, 비즈니스 핵심 로직 흐름을 방해하고 있는 것 같습니다! 전형적으로 Querydsl을 활용하여 리팩토링 되면 좋을 메서드라고 생각합니다!

@yousung1020 yousung1020 merged commit fa00f04 into main May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants