6주차 미션 [루가]#12
Conversation
…(record 사용, 엔드포인트 수정 및 스웨거 명세 추가)
…Id를 경로 변수로 받도록 수정
…tId를 경로 변수로 받도록 수정
|
수고하셨습니다 ~! |
|
미션 수고하셨습니다:) |
yangjiae12
left a comment
There was a problem hiding this comment.
수고하셨습니다~ dto만 record로 통일시키면 좋을 것 같아요
| List<MissionResDto.MissionDto> missions = slice.getContent().stream() | ||
| .map(um -> MissionResDto.MissionDto.builder() | ||
| .missionId(um.getMission().getId()) | ||
| .title(um.getMission().getBody()) | ||
| .point(um.getMission().getAward()) | ||
| .status(um.getStatus()) | ||
| .build()) | ||
| .toList(); | ||
|
|
||
| return MissionResDto.MissionListResDto.builder() | ||
| .missions(missions) | ||
| .hasNext(slice.hasNext()) | ||
| .build(); |
There was a problem hiding this comment.
비스 계층은 비즈니스 흐름을 제어하는 데 집중해야 하며, 객체 간 변환은 별도의 Converter 클래스로 위임하는 것이 좋습니다!
| User user = userRepository.findById(1L) | ||
| .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 유저입니다.")); |
There was a problem hiding this comment.
앞선 주차에 정의한 도메인별 Custom Exception를 활용하여 에러를 던지면 좋을 거 같아요
| .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 유저입니다.")); | ||
|
|
||
| MissionStatus missionStatus = MissionStatus.valueOf(status); | ||
| Slice<UserMission> slice = userMissionRepository.findByUserAndStatus( |
There was a problem hiding this comment.
Page 대신 Slice를 사용한 점이 좋은 것 같습니다! 이는 전체 데이터 개수를 세는 COUNT 쿼리를 생략할 수 있어, 데이터 양이 많아질수록 성능상 이점이 큽니다. 무한 스크롤 UI를 고려했을 때 적절한 선택이에요👍
| UserMission userMission = userMissionRepository.findById(userMissionId) | ||
| .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 미션입니다.")); | ||
| userMission.complete(); | ||
| return MissionResDto.MissionSuccessResDto.builder() | ||
| .missionId(userMission.getMission().getId()) | ||
| .completedAt(userMission.getCompletedAt()) | ||
| .build(); |
| @Getter | ||
| @Builder | ||
| @AllArgsConstructor | ||
| @NoArgsConstructor | ||
| public static class MissionListResDto { | ||
| private List<MissionDto> missions; | ||
| private Boolean hasNext; | ||
| } |
There was a problem hiding this comment.
모든 도메인에서 공용으로 사용할 수 있는 페이징 DTO를 만들어 활용하면 좋을 거 같습니다!
| Review review = Review.builder() | ||
| .body(request.content()) | ||
| .grade(request.rating()) | ||
| .restaurant(restaurant) | ||
| .user(user) | ||
| .build(); | ||
|
|
||
| Review saved = reviewRepository.save(review); | ||
| return ReviewResDto.CreateReviewResDto.builder() | ||
| .reviewId(saved.getId()) | ||
| .createdAt(saved.getDate().atStartOfDay()) | ||
| .build(); |
There was a problem hiding this comment.
이전에 말한 것처럼 Converter로 분리해주시면 됩니다~
|
|
||
| @Tag(name = "User", description = "유저 관련 API") | ||
| @RestController | ||
| @RequestMapping("/api") |
There was a problem hiding this comment.
다른 도메인과 동일하게 /api/(도메인)의 형태로 쓰면 좋을 거 같습니다
| public static class SignupReqDto { | ||
| private String name; | ||
| private String email; | ||
| private String password; | ||
| private String phone; | ||
| private String address; |
| User user = User.builder() | ||
| .name(request.getName()) | ||
| .email(request.getEmail()) | ||
| .phone(request.getPhone()) | ||
| .address(request.getAddress()) | ||
| .build(); | ||
| User saved = userRepository.save(user); | ||
| return UserResDto.SignupResDto.builder() | ||
| .userId(saved.getId()) | ||
| .createdAt(saved.getCreatedAt()) | ||
| .build(); |
| // Member | ||
| MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "MEMBER4001", "사용자를 찾을 수 없음"), | ||
| MEMBER_ALREADY_EXISTS(HttpStatus.BAD_REQUEST, "MEMBER4002", "이미 존재하는 회원임"), | ||
|
|
||
| // Mission | ||
| MISSION_NOT_FOUND(HttpStatus.NOT_FOUND, "MISSION4001", "미션을 찾을 수 없음"), | ||
| MISSION_ALREADY_COMPLETED(HttpStatus.BAD_REQUEST, "MISSION4002", "이미 완료된 미션"), | ||
|
|
||
| // Review | ||
| REVIEW_NOT_FOUND(HttpStatus.NOT_FOUND, "REVIEW4001", "리뷰를 찾을 수 없음"), | ||
|
|
||
| // Home | ||
| REGION_NOT_FOUND(HttpStatus.NOT_FOUND, "HOME4001", "해당 지역을 찾을 수 없음"); |
There was a problem hiding this comment.
도메인별로 에러 핸들링하고 있기 때문에 해당 파일이 아닌 도메인별 ErrorStatus를 활용해주시면 될 것 같습니다
📌 구현 결과
[도메인 별 스웨거]
[DTO]

❓ 리뷰 요청
🤔 질문
💬
기타 공유 사항