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 추가 #33

Merged
merged 20 commits into from
Dec 24, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
0c07585
[test]: 공연 정보 조회 API controller test 추가
ssssujini99 Dec 24, 2023
1ca4e5b
[feat]: 공연 정보 조회 API 추가
ssssujini99 Dec 24, 2023
b9b2d95
[chore]: core모듈에 jackson 라이브러리 추가
ssssujini99 Dec 24, 2023
f6f57c9
[test]: 공연 정보 조회 Application test 추가
ssssujini99 Dec 24, 2023
7dda6b5
[feat]: 공연 정보 조회 Application, 응답 DTO 추가
ssssujini99 Dec 24, 2023
2f14b7c
[feat]: NotFoundException 공통 예외 추가
ssssujini99 Dec 24, 2023
789c88d
[feat]: ShowErrorCode - Show 도메인 에러 코드 추가
ssssujini99 Dec 24, 2023
12f1aff
[refactor]: Show 모든 도메인에 AllArgsConstructor 추가
ssssujini99 Dec 24, 2023
e9ab71a
[test]: ShowRepositoryAdaptorTest 추가
ssssujini99 Dec 24, 2023
6638025
[feat]: ShowRepository, ShowRepositoryAdaptor 추가
ssssujini99 Dec 24, 2023
210a340
[feat]: PlaceRepository, PlaceRepositoryAdaptor 추가
ssssujini99 Dec 24, 2023
5eee542
[feat]: ApiExceptionHandler에 NotFoundException 추가
ssssujini99 Dec 24, 2023
07ed441
[docs]: show_dummy.sql 더미데이터 파일 추가
ssssujini99 Dec 24, 2023
334fabc
[refactor]: DataJpaTestSupport 옵션 설정 추가
ssssujini99 Dec 24, 2023
eb5218a
[fix]: NotFoundException, ExceptionHandler 수정
ssssujini99 Dec 24, 2023
caa42ae
Merge branch 'dev' into feat/#22/show-details-api
ssssujini99 Dec 24, 2023
babb762
[fix]: conflict 해결
ssssujini99 Dec 24, 2023
6c88622
[refactor]: Optional orElseThrow로 처리
ssssujini99 Dec 24, 2023
23b8021
[refactor]: 에러 메시지 검증 추가
ssssujini99 Dec 24, 2023
300c112
[refactor]: @AllArgsConstructor 대신 생성자로 리팩토링
ssssujini99 Dec 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,14 @@ public ErrorResponseTemplate handleMethodArgumentNotValidException(

return new ErrorResponseTemplate(message, ARGUMENT_NOT_VALID_ERROR_CODE);
}

@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(NotFoundException.class)
public ErrorResponseTemplate handleNotFoundException(
NotFoundException e
) {
log.error("NotFoundException : ", e);
return new ErrorResponseTemplate(e.getMessage(), e.getCode());
}

}
25 changes: 25 additions & 0 deletions api/src/main/java/dev/hooon/show/ShowDetailApiController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package dev.hooon.show;

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.RestController;

import dev.hooon.show.application.ShowService;
import dev.hooon.show.dto.response.ShowDetailsInfoResponse;
import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
public class ShowDetailApiController {

private final ShowService showService;

@GetMapping("/api/shows/{show_id}")
public ResponseEntity<ShowDetailsInfoResponse> getShowDetailInfo(
@PathVariable("show_id") Long showId
) {
ShowDetailsInfoResponse showDetailsInfoResponse = showService.getShowDetailInfo(showId);
return ResponseEntity.ok(showDetailsInfoResponse);
}
}
48 changes: 48 additions & 0 deletions api/src/test/java/dev/hooon/show/ShowDetailApiControllerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package dev.hooon.show;

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

import dev.hooon.common.support.ApiTestSupport;

@DisplayName("[ShowDetailApiController API 테스트]")
@Sql("/sql/show_dummy.sql")
class ShowDetailApiControllerTest extends ApiTestSupport {

@Autowired
private MockMvc mockMvc;

@DisplayName("[공연 아이디를 통해 API 를 호출하면 해당 공연의 세부 정보를 조회할 수 있다]")
@Test
void getShowDetailInfoTest() throws Exception {
// when
ResultActions resultActions = mockMvc.perform(
MockMvcRequestBuilders
.get("/api/shows/1")
);

// then
resultActions.andExpectAll(
status().isOk(),

jsonPath("$.showName").value("레미제라블"),
jsonPath("$.showStartDate").value("2023-10-10"),
jsonPath("$.showEndDate").value("2023-10-12"),
jsonPath("$.showTime").value(150),
jsonPath("$.showIntermissionTime").value(15),
jsonPath("$.showAgeLimit").value("만 8세 이상"),

jsonPath("$.placeDetailsInfo.showPlaceName").value("블루스퀘어 신한카드홀"),
jsonPath("$.placeDetailsInfo.showPlaceContactInfo").value("1544-1591"),
jsonPath("$.placeDetailsInfo.showPlaceAddress").value("서울특별시 용산구 이태원로 294 블루스퀘어(한남동)"),
jsonPath("$.placeDetailsInfo.showPlaceUrl").value("http://www.bluesquare.kr/index.asp")
);
}
}
1 change: 1 addition & 0 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ dependencies {
runtimeOnly 'org.postgresql:postgresql'
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.fasterxml.jackson.core:jackson-databind'
//테스트 픽쳐에서 사용할 의존성
testFixturesImplementation 'org.springframework.boot:spring-boot-starter-test'
testFixturesImplementation "org.testcontainers:testcontainers:1.19.3"
Expand Down
16 changes: 16 additions & 0 deletions core/src/main/java/dev/hooon/show/application/ShowService.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package dev.hooon.show.application;

import java.util.List;
import java.util.Optional;

import org.springframework.stereotype.Service;

import dev.hooon.common.exception.NotFoundException;
import dev.hooon.show.domain.entity.Show;
import dev.hooon.show.domain.repository.SeatRepository;
import dev.hooon.show.domain.repository.ShowRepository;
import dev.hooon.show.dto.ShowMapper;
import dev.hooon.show.dto.query.SeatDateRoundDto;
import dev.hooon.show.dto.response.AbleBookingDateRoundResponse;
import dev.hooon.show.dto.response.ShowDetailsInfoResponse;
import dev.hooon.show.exception.ShowErrorCode;
import lombok.RequiredArgsConstructor;

@Service
Expand All @@ -16,8 +22,18 @@ public class ShowService {

private final SeatRepository seatRepository;

private final ShowRepository showRepository;

public AbleBookingDateRoundResponse getAbleBookingDateRoundInfo(Long showId) {
List<SeatDateRoundDto> seatDateRoundDtoList = seatRepository.findSeatDateRoundInfoByShowId(showId);
return ShowMapper.toSeatDateRoundResponse(seatDateRoundDtoList);
}

public ShowDetailsInfoResponse getShowDetailInfo(Long showId) {
Optional<Show> showOptional = showRepository.findById(showId);
if (showOptional.isEmpty()) {
throw new NotFoundException(ShowErrorCode.SHOW_NOT_FOUND);
}
Copy link
Member

Choose a reason for hiding this comment

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

orElseThrow() 로 처리하는게 어떨까요? 더 깔끔할거같아요 ㅎㅎ

return ShowMapper.toShowDetailInfoResponse(showOptional.get());
}
}
42 changes: 22 additions & 20 deletions core/src/main/java/dev/hooon/show/domain/entity/Show.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,40 +17,42 @@
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@Table(name = "show_table")
@NoArgsConstructor
@AllArgsConstructor
Copy link
Member

Choose a reason for hiding this comment

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

저희 @AllArgsConstructor 사용 안하기로 컨벤션 정했던거같아요!
그리고 이 생성자가 꼭 필요한가요?? 만약 필요하다면 별도로 생성자 구현하는게 좋을 것 같아요!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

테스트 시 데이터 insert를 위해서 필요해서 만들었습니다..!!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

넵 이거 생성자 추가로 변경하겠습니당

public class Show extends TimeBaseEntity {

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "show_id")
private Long id;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "show_id")
private Long id;

@Column(name = "show_name", nullable = false)
private String name;
@Column(name = "show_name", nullable = false)
private String name;

@Enumerated(STRING)
@Column(name = "show_category", nullable = false)
private ShowCategory category;
@Enumerated(STRING)
@Column(name = "show_category", nullable = false)
private ShowCategory category;

@Embedded
private ShowPeriod showPeriod;
@Embedded
private ShowPeriod showPeriod;

@Embedded
private ShowTime showTime;
@Embedded
private ShowTime showTime;

@Column(name = "show_age_limit", nullable = false)
private String showAgeLimit;
@Column(name = "show_age_limit", nullable = false)
private String showAgeLimit;

@Column(name = "show_total_seats")
private int totalSeats;
@Column(name = "show_total_seats")
private int totalSeats;

@ManyToOne(fetch = LAZY)
@JoinColumn(name = "show_place_id", nullable = false, foreignKey = @ForeignKey(value = NO_CONSTRAINT))
private Place place;
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "show_place_id", nullable = false, foreignKey = @ForeignKey(value = NO_CONSTRAINT))
private Place place;
}
10 changes: 6 additions & 4 deletions core/src/main/java/dev/hooon/show/domain/entity/ShowPeriod.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -14,11 +15,12 @@
@Embeddable
@EqualsAndHashCode
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor
public class ShowPeriod {

@Column(name = "show_start_date", nullable = false)
private LocalDate startDate;
@Column(name = "show_start_date", nullable = false)
private LocalDate startDate;

@Column(name = "show_end_date", nullable = false)
private LocalDate endDate;
@Column(name = "show_end_date", nullable = false)
private LocalDate endDate;
}
10 changes: 6 additions & 4 deletions core/src/main/java/dev/hooon/show/domain/entity/ShowTime.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -12,11 +13,12 @@
@Embeddable
@EqualsAndHashCode
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor
public class ShowTime {

@Column(name = "show_total_minutes", nullable = false)
private int totalMinutes;
@Column(name = "show_total_minutes", nullable = false)
private int totalMinutes;

@Column(name = "show_intermission_minutes", nullable = false)
private int intermissionMinutes;
@Column(name = "show_intermission_minutes", nullable = false)
private int intermissionMinutes;
}
26 changes: 14 additions & 12 deletions core/src/main/java/dev/hooon/show/domain/entity/place/Place.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,31 @@
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@Table(name = "place_table")
@NoArgsConstructor
@AllArgsConstructor
public class Place extends TimeBaseEntity {

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "place_id")
private Long id;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "place_id")
private Long id;

@Column(name = "place_name", nullable = false)
private String name;
@Column(name = "place_name", nullable = false)
private String name;

@Column(name = "place_contact_info")
private String contactInfo;
@Column(name = "place_contact_info")
private String contactInfo;

@Column(name = "place_address", nullable = false)
private String address;
@Column(name = "place_address", nullable = false)
private String address;

@Column(name = "place_url")
private String placeUrl;
@Column(name = "place_url")
private String placeUrl;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package dev.hooon.show.domain.repository;

import dev.hooon.show.domain.entity.place.Place;

public interface PlaceRepository {

Place save(Place place);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package dev.hooon.show.domain.repository;

import java.util.Optional;

import dev.hooon.show.domain.entity.Show;

public interface ShowRepository {

Optional<Show> findById(Long id);

Show save(Show show);
}
20 changes: 20 additions & 0 deletions core/src/main/java/dev/hooon/show/dto/ShowMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

import java.util.List;

import dev.hooon.show.domain.entity.Show;
import dev.hooon.show.dto.query.SeatDateRoundDto;
import dev.hooon.show.dto.response.AbleBookingDateRoundResponse;
import dev.hooon.show.dto.response.AbleBookingDateRoundResponse.AvailableDate;
import dev.hooon.show.dto.response.PlaceDetailsInfo;
import dev.hooon.show.dto.response.ShowDetailsInfoResponse;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

Expand All @@ -21,4 +24,21 @@ public static AbleBookingDateRoundResponse toSeatDateRoundResponse(List<SeatDate

return new AbleBookingDateRoundResponse(availableDates);
}

public static ShowDetailsInfoResponse toShowDetailInfoResponse(Show show) {
return new ShowDetailsInfoResponse(
show.getName(),
show.getShowPeriod().getStartDate(),
show.getShowPeriod().getEndDate(),
show.getShowTime().getTotalMinutes(),
show.getShowTime().getIntermissionMinutes(),
show.getShowAgeLimit(),
new PlaceDetailsInfo(
show.getPlace().getName(),
show.getPlace().getContactInfo(),
show.getPlace().getAddress(),
show.getPlace().getPlaceUrl()
Comment on lines +31 to +40
Copy link
Member

Choose a reason for hiding this comment

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

. 에 . 찍으면서 호출하는 패턴 대신 별도의 getter 를 구현하는게 좋다고 생각을 했었는데... 이건 별도로 구현할 게터가 너무 많아보이네요... 그냥 이대로 써도 괜찮을 것 같아요 ㅎㅎ

)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package dev.hooon.show.dto.response;

public record PlaceDetailsInfo(
String showPlaceName,
String showPlaceContactInfo,
String showPlaceAddress,
String showPlaceUrl
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package dev.hooon.show.dto.response;

import java.time.LocalDate;

import com.fasterxml.jackson.annotation.JsonFormat;

public record ShowDetailsInfoResponse(
String showName,
@JsonFormat(pattern = "yyyy-MM-dd")
LocalDate showStartDate,
@JsonFormat(pattern = "yyyy-MM-dd")
LocalDate showEndDate,
int showTime,
int showIntermissionTime,
String showAgeLimit,
PlaceDetailsInfo placeDetailsInfo
) {
}
15 changes: 15 additions & 0 deletions core/src/main/java/dev/hooon/show/exception/ShowErrorCode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package dev.hooon.show.exception;

import dev.hooon.common.exception.ErrorCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum ShowErrorCode implements ErrorCode {

SHOW_NOT_FOUND("공연을 찾을 수 없습니다.", "S_001");

private final String message;
private final String code;
}
Loading