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 구현 - #42 #62

Merged
merged 16 commits into from
Jul 11, 2024
Merged

Conversation

rlarlgnszx
Copy link
Member

@rlarlgnszx rlarlgnszx commented Jul 11, 2024

🔥Pull requests

아 내일 PR 에딧할게용 ㅎㄱㅅㅎ
⛳️ 작업한 브랜치

👷 작업한 내용

  • 작성한 로직은 다음과 같습니다
    1. Course생성에는 다음의 내용이 필요합니다
    • 코스에 등록할 이미지
    • 코스에 등록할 장소
    • 코스에 등록할 태그
    1. 따라서 사진 + List 구현을 위해 RequestPart 방식을 사용했습니다.
      @PostMapping(value = "/create", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE})
      public ResponseEntity<Void> createCourse(
      @RequestHeader final Long userId,
      @RequestPart("course") final CourseCreateReq courseCreateReq,
      @RequestPart("tags") final List<TagCreateReq> tags,
      @RequestPart("places") final List<CoursePlaceGetReq> places,
      @RequestPart("images") final List<MultipartFile> images
      ) {
      Course course = courseService.createCourse(userId, courseCreateReq, places, images);
  1. Course를 저장후 Tag,Place, Image 저장에 대한 로직은 비동기적으로 이루어집니다.
  • 이유는 Course를 생성하는데 연결된 Tag,Place,Imaage는 Course를 참조하고 있을뿐 서로 겹치는 경우가 아니기 떄문에 Course를 저장 "후" Place, Image, Tag 를 비동기적으로 작성하게 했습니다.
    • 구조는 다음과 같습니다.
    1. Controller
    2. CourseService 에서 Course 저장 및 이미지 저장 실행
      -
      Course course = courseService.createCourse(userId, courseCreateReq, places, images);
    3. Tag,Place 저장소를 상속받은 CourseFacade 에서 Course를 가지고 비동기적으로 작동
    • courseFacade.createCoursePlace(places, course);
      courseFacade.createCourseTags(tags, course);
    • @Service
      @RequiredArgsConstructor(access = AccessLevel.PROTECTED)
      @Transactional(readOnly = true)
      public class CourseFacade {
      private final CoursePlaceService coursePlaceService;
      private final CourseTagService courseTagService;
      private final ImageService imageService;
      public Image findFirstByCourseOrderBySequenceAsc(final Course course) {
      return imageService.findFirstByCourseOrderBySequenceAsc(course);
      }
      public float findTotalDurationByCourseId(final Long id) {
      return coursePlaceService.findTotalDurationByCourseId(id);
      }
      @Transactional
      public String createImage(final List<MultipartFile> images, final Course course) {
      return imageService.saveImages(images, course);
      }
      @Async
      public void createCourseTags(final List<TagCreateReq> tags, final Course course) {
      courseTagService.createCourseTags(tags, course);
      }
      @Async
      public void createCoursePlace(final List<CoursePlaceGetReq> places, final Course course) {
      coursePlaceService.createCoursePlace(places, course);
      }
      }

🚨 참고 사항

📟 관련 이슈

Copy link
Contributor

@gardening-y gardening-y left a comment

Choose a reason for hiding this comment

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

이미지 처리하고 어려운 뷰인데.. 진짜 진짜 수고하셨습니다~!!! 김기훈 최고🙌

Copy link
Contributor

Choose a reason for hiding this comment

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

사용 되는 곳이 없는 것 같아요! 확인 한 번 해주세요~

Comment on lines 62 to 63
return ResponseEntity.created(
URI.create(course.getId().toString())).build();
Copy link
Contributor

Choose a reason for hiding this comment

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

courseId를 전달해주기 위함이면 dto로 만들어서 Long 값으로 전달해주는게 좋을 것 같아요..!
추가로 지금 Void 반환이라 반환값이 없습니다! ex) return ResponseEntity.status(HttpStatus.CREATED).body(dto).build();

Comment on lines +38 to +40
public static CourseCreateReq of(final String title,final LocalDate date,final LocalTime startAt,
final String country,final String city,final String description,
int cost) {
Copy link
Contributor

Choose a reason for hiding this comment

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

쉼표 뒤 띄어쓰기.. 그리고 두줄로 맞추는건 어떤지..?ㅎㅎ

import org.dateroad.tag.domain.DateTagType;

@Getter
@Setter
Copy link
Contributor

Choose a reason for hiding this comment

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

@Setter는 사용되지 않는다면 지워주시는게 좋을 것 같아요!

Comment on lines +88 to +94
courseRegisterReq.getTitle(),
courseRegisterReq.getDescription(),
courseRegisterReq.getCountry(),
courseRegisterReq.getCity(),
courseRegisterReq.getCost(),
courseRegisterReq.getDate(),
courseRegisterReq.getStartAt(),
Copy link
Contributor

Choose a reason for hiding this comment

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

create에서 CourseRegisterReq를 변수로 받아서 좀 더 가독성 좋게 짜는 방향도 좋을 것 같아요!

Comment on lines 32 to 33
private final CourseService courseService;
private final CourseFacade courseFacade;
Copy link
Contributor

Choose a reason for hiding this comment

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

Facade는 기존의 Service에서 많은 의존성을 주입받는 것을 개선하기 위해 한 단계 계층을 더 둔 패턴인데 Service랑 같이 사용하면 패턴의 의미가 없을 것 같습니다..!
추가로 로직을 확인해보니 Facade 패턴을 적용한 것이 아닌 비동기 처리를 위해 Service를 분리하신거 같은데 CourseAsyncService와 같은 네이밍은 어떨까요?!

totalTime
);
Course saveCourse = courseRepository.save(course);
course.setThumbnail(courseFacade.createImage(images, saveCourse));
Copy link
Contributor

Choose a reason for hiding this comment

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

setThumbnail에서 createImage를 실행하는 것보다 먼저 createImage를 통해 우선적으로 이미지를 저장하고, 리스트로 반환된 String 중 처음 온 String만 변수로 담아서 setTumbnail에 저장하는 방식으로 로직을 분리하면 어떨까요?!

Comment on lines 34 to 37
@Transactional
public String createImage(final List<MultipartFile> images, final Course course) {
return imageService.saveImages(images, course);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

추가로 이 로직의 saveImages에서 images가 저장된 후 images 첫 url 만 반환되는데 이 로직을 한번에 묶어서 saveImages라고 정의하는 것보다 saveImages에는 이미지들을 저장하는 로직만 작성하고, 전체리스트를 받아온 후 첫번째 url만 따로 반환하는 메서드를 생성해서 그걸 사용하는게 어떨까요? 코드를 이해하거나 분리해서 재사용하는 측면에서 장점이 있을 것 같습니다!

@rlarlgnszx rlarlgnszx merged commit bef4ae2 into develop Jul 11, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FEAT] 데이트 코스 등록 API
2 participants