-
Notifications
You must be signed in to change notification settings - Fork 5
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
[Feature] - 여행 계획 상세 조회 API 구현 #56
Changes from all commits
837b7c8
a262831
b6bd753
1d36bdd
f25a089
63d0088
6465dd6
bb36c54
0afa90f
6a1eac2
7d57b0c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package woowacourse.touroot.global.exception; | ||
|
||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.RestControllerAdvice; | ||
import woowacourse.touroot.global.exception.dto.ExceptionResponse; | ||
|
||
@Slf4j | ||
@RestControllerAdvice | ||
public class GlobalExceptionHandler { | ||
|
||
@ExceptionHandler(BadRequestException.class) | ||
public ResponseEntity<ExceptionResponse> handleBadRequestException(BadRequestException exception) { | ||
log.info("BAD_REQUEST_EXCEPTION :: message = {}", exception.getMessage()); | ||
ExceptionResponse data = new ExceptionResponse(exception.getMessage()); | ||
return ResponseEntity.badRequest() | ||
.body(data); | ||
} | ||
Comment on lines
+13
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 지금은 400 에러밖에 없지만, 이후 다양한 번호의 에러를 응답해 줘야 할때 조금 복잡해질수도 있을 것 같아요..! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예외 자체에 status code를 두는 방법 좋은 것 같습니다! 예외 메시지도 아예 둬버리면 더 통일되게 관리할 수도 있을 것 같네용 |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package woowacourse.touroot.global.exception.dto; | ||
|
||
public record ExceptionResponse(String message) { | ||
} | ||
Comment on lines
+1
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재는 예외의 종류가 많지 않아서 이정도가 담백한 구현인 듯 해요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 에러 코드 도입하는건 저도 긍정적으로 생각합니다~! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 좀 더 표준화된 방식인 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. problem detail이 제공되는건 처음 알았네요~! 예외 리팩토링 진행 시 반영하겠습니다 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,62 @@ | ||
package woowacourse.touroot.travelplan.controller; | ||
|
||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.Parameter; | ||
import io.swagger.v3.oas.annotations.media.Content; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import jakarta.validation.Valid; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import woowacourse.touroot.travelplan.dto.TravelPlanCreateRequest; | ||
import woowacourse.touroot.travelplan.dto.TravelPlanCreateResponse; | ||
import org.springframework.web.bind.annotation.*; | ||
import woowacourse.touroot.global.exception.dto.ExceptionResponse; | ||
import woowacourse.touroot.travelplan.dto.request.TravelPlanCreateRequest; | ||
import woowacourse.touroot.travelplan.dto.response.TravelPlanCreateResponse; | ||
import woowacourse.touroot.travelplan.dto.response.TravelPlanResponse; | ||
import woowacourse.touroot.travelplan.service.TravelPlanService; | ||
|
||
@Tag(name = "여행기") | ||
@Tag(name = "여행 계획") | ||
@RequiredArgsConstructor | ||
@RestController | ||
@RequestMapping("/api/v1/travel-plans") | ||
public class TravelPlanController { | ||
|
||
private final TravelPlanService travelPlanService; | ||
|
||
@Operation(summary = "여행기 생성") | ||
@Operation( | ||
summary = "여행 계획 생성", | ||
responses = { | ||
@ApiResponse( | ||
responseCode = "400", | ||
description = "Body에 유효하지 않은 값이 존재하거나 지난 날짜에 대한 계획을 생성할 때", | ||
content = @Content(schema = @Schema(implementation = ExceptionResponse.class)) | ||
) | ||
} | ||
) | ||
@PostMapping | ||
public ResponseEntity<TravelPlanCreateResponse> createTravelPlan(@Valid @RequestBody TravelPlanCreateRequest request) { | ||
public ResponseEntity<TravelPlanCreateResponse> createTravelPlan( | ||
@Valid @RequestBody TravelPlanCreateRequest request | ||
) { | ||
TravelPlanCreateResponse data = travelPlanService.createTravelPlan(request); | ||
return ResponseEntity.ok() | ||
.body(data); | ||
return ResponseEntity.ok(data); | ||
} | ||
|
||
@Operation( | ||
summary = "여행 계획 상세 조회", | ||
responses = { | ||
@ApiResponse( | ||
responseCode = "400", | ||
description = "존재하지 않은 여행 계획을 조회할 때", | ||
content = @Content(schema = @Schema(implementation = ExceptionResponse.class)) | ||
) | ||
} | ||
) | ||
@GetMapping("/{id}") | ||
public ResponseEntity<TravelPlanResponse> readTravelPlan( | ||
@Parameter(description = "여행 계획 id") @PathVariable Long id | ||
) { | ||
TravelPlanResponse data = travelPlanService.readTravelPlan(id); | ||
return ResponseEntity.ok(data); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package woowacourse.touroot.travelplan.dto.response; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.Builder; | ||
import woowacourse.touroot.travelplan.domain.TravelPlanDay; | ||
|
||
import java.time.LocalDate; | ||
import java.util.List; | ||
|
||
@Builder | ||
public record TravelPlanDayResponse( | ||
@Schema(description = "여행 일자") LocalDate date, | ||
@Schema(description = "여행 장소별 정보") List<TravelPlanPlaceResponse> places | ||
) { | ||
|
||
public static TravelPlanDayResponse of( | ||
TravelPlanDay planDay, | ||
List<TravelPlanPlaceResponse> places | ||
) { | ||
return TravelPlanDayResponse.builder() | ||
.date(planDay.getCurrentDate()) | ||
.places(places) | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package woowacourse.touroot.travelplan.dto.response; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.Builder; | ||
import woowacourse.touroot.place.domain.Place; | ||
|
||
@Builder | ||
public record TravelPlanLocationResponse( | ||
@Schema(description = "여행 장소 위도") String lat, | ||
@Schema(description = "여행 계획 경도") String lng | ||
) { | ||
|
||
public static TravelPlanLocationResponse from(Place place) { | ||
return TravelPlanLocationResponse.builder() | ||
.lat(place.getLatitude()) | ||
.lng(place.getLongitude()) | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package woowacourse.touroot.travelplan.dto.response; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.Builder; | ||
import woowacourse.touroot.place.domain.Place; | ||
import woowacourse.touroot.travelplan.domain.TravelPlanPlace; | ||
|
||
@Builder | ||
public record TravelPlanPlaceResponse( | ||
@Schema(description = "여행 장소 이름") String placeName, | ||
@Schema(description = "여행 장소 위치") TravelPlanLocationResponse location, | ||
@Schema(description = "여행 장소 설명") String description | ||
) { | ||
|
||
public static TravelPlanPlaceResponse from(TravelPlanPlace planPlace) { | ||
Place place = planPlace.getPlace(); | ||
TravelPlanLocationResponse locationResponse = TravelPlanLocationResponse.from(place); | ||
|
||
return TravelPlanPlaceResponse.builder() | ||
.placeName(place.getName()) | ||
.location(locationResponse) | ||
.description(planPlace.getDescription()) | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package woowacourse.touroot.travelplan.dto.response; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.Builder; | ||
import woowacourse.touroot.travelplan.domain.TravelPlan; | ||
|
||
import java.time.LocalDate; | ||
import java.util.List; | ||
|
||
@Builder | ||
public record TravelPlanResponse( | ||
@Schema(description = "여행 계획 id") Long id, | ||
@Schema(description = "여행 계획 제목") String title, | ||
@Schema(description = "여행 시작일") LocalDate startDate, | ||
@Schema(description = "여행 계획 날짜별 정보") List<TravelPlanDayResponse> days | ||
) { | ||
|
||
public static TravelPlanResponse of(TravelPlan travelPlan, List<TravelPlanDayResponse> days) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 정적 팩토리 메소드 네이밍 👍 |
||
return TravelPlanResponse.builder() | ||
.id(travelPlan.getId()) | ||
.title(travelPlan.getTitle()) | ||
.startDate(travelPlan.getStartDate()) | ||
.days(days) | ||
.build(); | ||
} | ||
} |
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.
예외 핸들러 확인했습니다.
다음에 작성할 일이 있으면 비슷한 포맷으로 저도 작성하도록 할게요!