-
Notifications
You must be signed in to change notification settings - Fork 37
[1주차] 멀티모듈 구성 및 영화 목록 조회 기능 설계 #24
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
Open
choi1204
wants to merge
8
commits into
hanghae-skillup:main
Choose a base branch
from
choi1204:week1_choi1204
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 4 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
b896b67
feat : init project
choi1204 5883d2f
feat : db 설정 추가
choi1204 95e8934
feat : 과제 구현
choi1204 b696bad
feat : read me 추가
choi1204 f6fc35a
feat : resuful하게 api endpoint수정
choi1204 d2526ae
feat : 시트 정보 외부 테이블로 변경
choi1204 9a0d793
feat : 시트 정보 외부 테이블로 변경
choi1204 3e68d65
feat : 시트 추가로 인해서, sql 및 http 변경
choi1204 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| /gradlew text eol=lf | ||
| *.bat text eol=crlf | ||
| *.jar binary |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| HELP.md | ||
| .gradle | ||
| build/ | ||
| !gradle/wrapper/gradle-wrapper.jar | ||
| !**/src/main/**/build/ | ||
| !**/src/test/**/build/ | ||
|
|
||
| ### STS ### | ||
| .apt_generated | ||
| .classpath | ||
| .factorypath | ||
| .project | ||
| .settings | ||
| .springBeans | ||
| .sts4-cache | ||
| bin/ | ||
| !**/src/main/**/bin/ | ||
| !**/src/test/**/bin/ | ||
|
|
||
| ### IntelliJ IDEA ### | ||
| .idea | ||
| *.iws | ||
| *.iml | ||
| *.ipr | ||
| out/ | ||
| !**/src/main/**/out/ | ||
| !**/src/test/**/out/ | ||
|
|
||
| ### NetBeans ### | ||
| /nbproject/private/ | ||
| /nbbuild/ | ||
| /dist/ | ||
| /nbdist/ | ||
| /.nb-gradle/ | ||
|
|
||
| ### VS Code ### | ||
| .vscode/ | ||
|
|
||
| ### Kotlin ### | ||
| .kotlin |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| # 프로젝트 README | ||
|
|
||
| ## 프로젝트 소개 | ||
| 이 프로젝트는 영화 상영 정보와 관련된 기능을 제공하는 **멀티 모듈 프로젝트**입니다. 영화관, 영화, 상영 일정, 상영관 등의 정보를 효율적으로 관리하고 제공하는 시스템으로 설계되었습니다. 코드는 Kotlin과 Spring Boot를 기반으로 작성되었으며, 도메인 중심 설계를 적용하였습니다. | ||
|
|
||
| --- | ||
|
|
||
| ## 모듈 구조 | ||
|
|
||
| ### 1. **`cinema-domain`** | ||
| - **역할:** | ||
| - 프로젝트의 핵심 비즈니스 로직과 엔티티가 정의된 모듈입니다. | ||
| - 데이터베이스와의 상호작용을 위한 JPA 엔티티와 Repository를 포함합니다. | ||
| - **주요 패키지 구성:** | ||
| - `cinema`: 영화관 정보 (Cinema) | ||
| - `movie`: 영화 정보 (Movie, Genre, MovieRating 등) | ||
| - `schedule`: 영화 상영 일정 (MovieSchedule) | ||
| - `theater`: 상영관 정보 (Theater) | ||
| - `infra.jpa`: JPA Repository 및 QueryDSL 설정 | ||
|
|
||
| ### 2. **`cinema-api`** | ||
| - **역할:** | ||
| - 외부 사용자에게 API를 제공하는 모듈입니다. | ||
| - Controller와 DTO 계층을 포함하여 클라이언트와의 인터페이스를 담당합니다. | ||
| - **주요 패키지 구성:** | ||
| - `application`: 비즈니스 로직을 처리하는 Service 계층 | ||
| - `interface`: API 요청을 처리하는 Controller와 DTO 정의 | ||
|
|
||
| ### 3. **`cinema-admin`** | ||
| - **역할:** | ||
| - 관리자용 기능(예: 상영 스케줄 관리)을 제공하는 모듈입니다. | ||
|
|
||
| --- | ||
|
|
||
| ## 아키텍처 설명 | ||
|
|
||
| ### 전체 아키텍처 | ||
|
|
||
| - **멀티 모듈 설계:** | ||
| - `cinema-domain`: 핵심 도메인 로직과 데이터 액세스를 처리합니다. | ||
| - `cinema-api`: 사용자 요청을 처리하고 비즈니스 로직을 호출합니다. | ||
| - `cinema-admin`: 관리자 기능을 제공합니다. | ||
|
|
||
| - **계층 구조:** | ||
| - **Controller (API 모듈):** 사용자 요청을 받아 Service 계층으로 전달합니다. | ||
| - **Service (Domain 모듈):** 비즈니스 로직을 처리하며, Repository와 상호작용합니다. | ||
| - **Repository (Domain 모듈):** 데이터베이스와 직접적으로 통신합니다. | ||
|
|
||
| ### QueryDSL 적용 | ||
| - `cinema-domain` 모듈에 QueryDSL을 설정하여 동적 쿼리를 지원합니다. | ||
| - `MovieScheduleRepositoryCustom` 인터페이스와 `MovieScheduleRepositoryCustomImpl` 구현체를 통해 확장된 Repository 기능을 제공합니다. | ||
|
|
||
| --- | ||
|
|
||
| ## 데이터베이스 테이블 설계 | ||
|
|
||
| ### 주요 테이블 | ||
|
|
||
| #### 1. `cinema` | ||
| - **영화관 정보를 저장** | ||
| - 주요 컬럼: | ||
| - `id` (PK): 영화관 ID | ||
| - `name`: 영화관 이름 | ||
| - `address`: 영화관 주소 | ||
| - `contact_number`: 연락처 | ||
|
|
||
| #### 2. `movie` | ||
| - **영화 정보를 저장** | ||
| - 주요 컬럼: | ||
| - `id` (PK): 영화 ID | ||
| - `title`: 영화 제목 | ||
| - `genre`: 영화 장르 | ||
| - `movie_rating`: 영상물 등급 | ||
| - `release_date`: 개봉일 | ||
| - `running_time_minutes`: 러닝 타임 | ||
| - `thumbnail_url`: 포스터 URL | ||
|
|
||
| #### 3. `theater` | ||
| - **상영관 정보를 저장** | ||
| - 주요 컬럼: | ||
| - `id` (PK): 상영관 ID | ||
| - `title`: 상영관 이름 | ||
| - `seat_layout`: 좌석 배치 | ||
| - `cinema_id` (FK): 영화관 ID | ||
|
|
||
| #### 4. `movie_schedule` | ||
| - **영화 상영 일정을 저장** | ||
| - 주요 컬럼: | ||
| - `id` (PK): 상영 일정 ID | ||
| - `start_at`: 상영 시작 시간 | ||
| - `end_at`: 상영 종료 시간 | ||
| - `movie_id` (FK): 영화 ID | ||
| - `theater_id` (FK): 상영관 ID | ||
| - `cinema_id` (FK): 영화관 ID | ||
|
|
||
| --- | ||
|
|
||
| ## 실행 방법 | ||
| ``` bash | ||
| docker-compose -f compose.yaml up -d | ||
|
|
||
| ``` | ||
|
|
||
| ## 테스트 | ||
| http.movie.http | ||
|
|
||
| ## 고민포인트 | ||
|
|
||
| #### UI에서 제공해준 페이지네이션 | ||
|
|
||
| UI는 영화와 상영관 단위로 리스트를 제공하며, 하위에 시간표를 표시해야 했습니다. | ||
| 하지만 페이지네이션을 고려하면 (영화, 상영관) 의 수가 요청한 수를 제공할 수있는 구조여야 합니다. | ||
|
|
||
| 최초 접근 방법은 고유한 영화와 상영관 쌍을 먼저 뽑은 후, 시간표를 추가 쿼리로 조회하려 했습니다. | ||
| 그러나 전체 정렬을 movie의 개봉일 기준으로 해야 했기 때문에 DISTINCT를 사용할 수 없었습니다. | ||
|
|
||
| 최종 대안: | ||
|
|
||
| 상영관 정보를 시간표와 동일한 위계로 내려 그룹핑을 애플리케이션 레벨에서 처리했습니다. | ||
| 이를 통해 영화 개봉일로 정렬하면서도 UI 요구사항을 만족시킬 수 있었습니다. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| plugins { | ||
| kotlin("kapt") version "2.1.0" | ||
| kotlin("jvm") version "1.9.25" | ||
| kotlin("plugin.spring") version "1.9.25" | ||
| id("org.springframework.boot") version "3.4.1" | ||
| id("io.spring.dependency-management") version "1.1.7" | ||
| kotlin("plugin.jpa") version "1.9.25" | ||
| } | ||
|
|
||
| group = "com.study" | ||
| version = "0.0.1-SNAPSHOT" | ||
|
|
||
|
|
||
|
|
||
| allprojects { | ||
| repositories { | ||
| mavenCentral() | ||
| gradlePluginPortal() | ||
| } | ||
| } | ||
|
|
||
| subprojects { | ||
| apply { | ||
| plugin("org.jetbrains.kotlin.jvm") | ||
| plugin("org.jetbrains.kotlin.kapt") | ||
| plugin("org.springframework.boot") | ||
| plugin("io.spring.dependency-management") | ||
| plugin("org.jetbrains.kotlin.plugin.jpa") | ||
| plugin("org.jetbrains.kotlin.plugin.spring") | ||
| } | ||
| dependencyManagement { | ||
| imports { | ||
| mavenBom("com.querydsl:querydsl-bom:5.1.0") | ||
| } | ||
| } | ||
|
|
||
| dependencies { | ||
| implementation("com.fasterxml.jackson.module:jackson-module-kotlin") | ||
| implementation("org.jetbrains.kotlin:kotlin-reflect") | ||
| developmentOnly("org.springframework.boot:spring-boot-docker-compose") | ||
| testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") | ||
| testRuntimeOnly("org.junit.platform:junit-platform-launcher") | ||
| } | ||
|
|
||
| kotlin { | ||
| compilerOptions { | ||
| freeCompilerArgs.addAll("-Xjsr305=strict") | ||
| } | ||
| } | ||
|
|
||
| java { | ||
| toolchain { | ||
| languageVersion = JavaLanguageVersion.of(21) | ||
| } | ||
| } | ||
|
|
||
| allOpen { | ||
| annotation("jakarta.persistence.Entity") | ||
| annotation("jakarta.persistence.MappedSuperclass") | ||
| annotation("jakarta.persistence.Embeddable") | ||
| } | ||
|
|
||
| tasks.withType<Test> { | ||
| useJUnitPlatform() | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| plugins { | ||
| java | ||
| id("org.springframework.boot") | ||
| id("io.spring.dependency-management") | ||
| } | ||
|
|
||
|
|
||
| dependencies { | ||
| implementation(project(":cinema-domain")) | ||
| implementation("org.springframework.boot:spring-boot-starter-web") | ||
| testImplementation("org.springframework.boot:spring-boot-starter-test") | ||
| } |
13 changes: 13 additions & 0 deletions
13
cinema/cinema-admin/src/main/java/com/study/cinema/CinemaAdminApplication.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package com.study.cinema; | ||
|
|
||
| import org.springframework.boot.SpringApplication; | ||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
|
|
||
| @SpringBootApplication | ||
| public class CinemaAdminApplication { | ||
|
|
||
| public static void main(String[] args) { | ||
| SpringApplication.run(CinemaAdminApplication.class, args); | ||
| } | ||
|
|
||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| spring: | ||
| datasource: | ||
| url: jdbc:mysql://localhost:3306/cinema | ||
| username: user | ||
| password: password | ||
| driver-class-name: com.mysql.cj.jdbc.Driver | ||
| jpa: | ||
| hibernate: | ||
| ddl-auto: update | ||
| properties: | ||
| hibernate: | ||
| dialect: org.hibernate.dialect.MySQLDialect | ||
| sql: | ||
| init: | ||
| mode: always |
13 changes: 13 additions & 0 deletions
13
cinema/cinema-admin/src/test/java/com/study/cinema/CinemaAdminApplicationTests.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package com.study.cinema; | ||
|
|
||
| import org.junit.jupiter.api.Test; | ||
| import org.springframework.boot.test.context.SpringBootTest; | ||
|
|
||
| @SpringBootTest | ||
| class CinemaAdminApplicationTests { | ||
|
|
||
| @Test | ||
| void contextLoads() { | ||
| } | ||
|
|
||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| plugins { | ||
| kotlin("jvm") | ||
| kotlin("plugin.spring") | ||
| id("org.springframework.boot") | ||
| id("io.spring.dependency-management") | ||
| } | ||
| dependencies { | ||
| implementation(project(":cinema-domain")) | ||
| implementation("org.springframework.boot:spring-boot-starter-web") | ||
| testImplementation("org.springframework.boot:spring-boot-starter-test") | ||
| } |
11 changes: 11 additions & 0 deletions
11
cinema/cinema-api/src/main/kotlin/com/study/cinema/CinemaApiApplication.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package com.study.cinema | ||
|
|
||
| import org.springframework.boot.autoconfigure.SpringBootApplication | ||
| import org.springframework.boot.runApplication | ||
|
|
||
| @SpringBootApplication | ||
| class CinemaApiApplication | ||
|
|
||
| fun main(args: Array<String>) { | ||
| runApplication<CinemaApiApplication>(*args) | ||
| } |
12 changes: 12 additions & 0 deletions
12
cinema/cinema-api/src/main/kotlin/com/study/cinema/application/MovieScheduleSearchFacade.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package com.study.cinema.application | ||
|
|
||
| import com.study.cinema.domain.schedule.MovieScheduleQueryService | ||
| import org.springframework.stereotype.Component | ||
|
|
||
| @Component | ||
| class MovieScheduleSearchFacade( | ||
| private val movieScheduleQueryService: MovieScheduleQueryService | ||
| ) { | ||
| fun findByCinemaId(campaignId: Long) = | ||
| movieScheduleQueryService.findByCinemaId(campaignId) | ||
| } |
23 changes: 23 additions & 0 deletions
23
cinema/cinema-api/src/main/kotlin/com/study/cinema/interface/MovieController.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package com.study.cinema.`interface` | ||
|
|
||
| import com.study.cinema.application.MovieScheduleSearchFacade | ||
| import org.springframework.http.ResponseEntity | ||
| import org.springframework.web.bind.annotation.GetMapping | ||
| import org.springframework.web.bind.annotation.PathVariable | ||
| import org.springframework.web.bind.annotation.RequestMapping | ||
| import org.springframework.web.bind.annotation.RestController | ||
|
|
||
| @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) } | ||
| ) | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/api/v1/movies/{cinemaId}/theater-schedules
movies 다음에는 당연히 movieId가 와야 할거 같은데 cinemaId가 오네요.
REST API 원칙에 맞춰서 설계해보는건 어떨까요?
https://jojoldu.tistory.com/783