Conversation
youngxpepp
left a comment
There was a problem hiding this comment.
안녕하세요 현웅님. 이건홍 코치라고 합니다ㅎㅎ
실제 영화 예약 시스템을 생각하면서 개발했다는게 많이 느껴졌습니다. 특히 영화 조회 API에서요!
해당 부분은 코드 리뷰 남겼으니 꼭 확인해주시고 반영해주세요.
멀티 모듈 세팅이 어려우셨다니... 관련 내용을 첨부해드릴테니 천천히 확인하시면 좋겠습니다!
좋았던 점
- Movie 엔티티가 깔끔해서 좋았어요.
- enum 잘 활용해주셨어요
- 주석을 통해서 러닝 타임의 시간 단위를 언급해주셨습니다. 디테일 잘 챙겨주셨어요!
- api, domain 모듈을 잘 나눠주셨어요!
- 일반적인 영화관 예매 시스템을 떠올리며 개발한게 느껴집니다👍
- (영화 + 상영관) 을 묶었음 -> 이건 리뷰에서 말씀 드린 것처럼 수정해주세요!
- 영화관, 상영관을 분리함
아쉬운 점
- REST API 원칙을 조금만 더 확인해보면 어떨까요?
- API 요구사항을 다시 한번 확인해보는건 어떨까요? 그치만 일반적인 영화 예매 시스템을 떠올렸을 때 충분히 헷갈릴 수 있다고 생각합니다. 영화를 조회하는 api라고 생각해주세요.
- 아키텍처, ERD 등의 프로젝트 구조에 대한 내용이 README에 담겼으면 좋겠습니다.
| @Comment("장르") | ||
| @Enumerated(EnumType.STRING) | ||
| @Column(length = 50) | ||
| var genre: Genre = genre | ||
| protected set | ||
|
|
||
| @Comment("영상물 등급") | ||
| @Enumerated(EnumType.STRING) | ||
| @Column(length = 50) | ||
| var movieRating: MovieRating = movieRating | ||
| protected set |
| @Comment("러닝 타임 (분)") | ||
| var runningTimeMinutes: Int = runningTimeMinutes | ||
| protected set |
There was a problem hiding this comment.
다른 사람이 봤을 때 시간 단위를 모를 수 있거든요.
분 단위라고 알려주는 섬세함이 좋네요 ㅎㅎ
| @ManyToOne(fetch = FetchType.LAZY) | ||
| @JoinColumn(name = "theater_id") | ||
| val theater: Theater = theater | ||
|
|
||
| @ManyToOne(fetch = FetchType.LAZY) | ||
| @JoinColumn(name = "cinema_id") | ||
| val cinema: Cinema = theater.cinema |
| @RestController | ||
| @RequestMapping("api/v1/movies") | ||
| class MovieController( | ||
| private val movieScheduleSearchFacade: MovieScheduleSearchFacade | ||
| ) { | ||
|
|
||
| @GetMapping("{cinemaId}/theater-schedules") | ||
| fun findTheaterScheduleByCinemaId( | ||
| @PathVariable cinemaId: Long | ||
| ) = ResponseEntity.ok( | ||
| movieScheduleSearchFacade.findByCinemaId(cinemaId) | ||
| .map { MovieV1Dto.Response.MovieWithTheaterSchedule(it) } | ||
| ) |
There was a problem hiding this comment.
/api/v1/movies/{cinemaId}/theater-schedules
movies 다음에는 당연히 movieId가 와야 할거 같은데 cinemaId가 오네요.
REST API 원칙에 맞춰서 설계해보는건 어떨까요?
| fun findByCinemaId(cinemaId: Long): List<MovieInfo.MovieSchedule> { | ||
| val schedules = movieScheduleRepository.findByCinemaId(cinemaId) | ||
| return schedules.groupBy { it.movie.id } | ||
| .map { it.value } | ||
| .map { | ||
| MovieInfo.MovieSchedule(it.first().movie, it.sortedBy { it.startAt }) | ||
| } | ||
| .sortedByDescending { it.releaseDate } | ||
| } |
There was a problem hiding this comment.
UI는 영화와 상영관 단위로 리스트를 제공하며, 하위에 시간표를 표시해야 했습니다.
하지만 페이지네이션을 고려하면 (영화, 상영관) 의 수가 요청한 수를 제공할 수있는 구조여야 합니다.
최초 접근 방법은 고유한 영화와 상영관 쌍을 먼저 뽑은 후, 시간표를 추가 쿼리로 조회하려 했습니다.
그러나 전체 정렬을 movie의 개봉일 기준으로 해야 했기 때문에 DISTINCT를 사용할 수 없었습니다.
최종 대안:
상영관 정보를 시간표와 동일한 위계로 내려 그룹핑을 애플리케이션 레벨에서 처리했습니다.
위 질문에 대한 답변입니다.
(영화 + 상영관) 을 묶으려고 해서 발생한 문제라고 생각이 드네요.
영화를 위주로 데이터를 조회해주세요!
- 영화 정보
- 영화 제목
- 개봉일
- 썸네일
- 상영 정보 List (A~C)
- 범죄도시(상영관 A) 01:00 ~ 02:00
- 범죄도시(상영관 B) 02:00 ~ 03:00
- 범죄도시(상영관 C) 03:00 ~ 04:00
There was a problem hiding this comment.
네 감사합니다
현재 구조는 영화 위주로 묶어서 응답하고 있습니다.
시나리오 란에 제시해준 ux에서 영화를 상영관별로 묶여있어서 해당 관점에서 페이지네이션이 가능한 구조로 설계할려고해서 질문드렸습니다.
| @Comment("좌석 배치 정보") | ||
| var seatLayout: String = seatLayout | ||
| protected set |
There was a problem hiding this comment.
좌석에 대한 고민이 더 들어갔으면 좋겠습니다!
우리가 실제로 영화관 예매 시스템을 만든다고 생각해보세욥!
이번주 일정이 안나와서 늦게 작업해서 지각 제출합니다 ㅠㅠ
작업 내용
발생했던 문제와 해결 과정을 남겨 주세요.
UI는 영화와 상영관 단위로 리스트를 제공하며, 하위에 시간표를 표시해야 했습니다.
하지만 페이지네이션을 고려하면 (영화, 상영관) 의 수가 요청한 수를 제공할 수있는 구조여야 합니다.
최초 접근 방법은 고유한 영화와 상영관 쌍을 먼저 뽑은 후, 시간표를 추가 쿼리로 조회하려 했습니다.
그러나 전체 정렬을 movie의 개봉일 기준으로 해야 했기 때문에 DISTINCT를 사용할 수 없었습니다.
최종 대안:
상영관 정보를 시간표와 동일한 위계로 내려 그룹핑을 애플리케이션 레벨에서 처리했습니다.
이번 주차에서 고민되었던 지점이나, 어려웠던 점을 알려 주세요.
리뷰 포인트
기타 질문