Skip to content

Commit

Permalink
[Feature] - 여행기 작성 API 및 여행기 전체 조회 API 구현
Browse files Browse the repository at this point in the history
* feat: 여행기 작성 API를 위한 DTO 구현

* feat: 여행기 사진 엔티티 생성자 매개변수 순서 변경

* feat: 여행기 작성 API 구현

* feat: 메인 페이지를 위한 여행기 전체 목록 조회 API 구현

* chore: EOL 추가

* refactor: 불필요한 Bean validation 제거

* refactor: embedded DTO bean validation 추가

* chore: 실수로 제거한 필드 추가

* refactor: 패키지 구조 변경

* chore: 불필요한 final 제거

* refactor: 여행기 관련 도메인 조회 기능아 정적 팩토리 메소드를 활용하도록 개선
  • Loading branch information
hangillee authored Jul 21, 2024
1 parent 6b6bbcb commit 4de3070
Show file tree
Hide file tree
Showing 28 changed files with 472 additions and 191 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
package woowacourse.touroot.travelogue.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import java.net.URI;
import lombok.RequiredArgsConstructor;
import org.springdoc.core.converters.models.PageableAsQueryParam;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
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.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.travelogue.dto.TravelogueResponse;
import woowacourse.touroot.travelogue.dto.request.TravelogueRequest;
import woowacourse.touroot.travelogue.dto.response.TravelogueResponse;
import woowacourse.touroot.travelogue.service.TravelogueFacadeService;

@Tag(name = "여행기")
Expand All @@ -20,9 +30,29 @@ public class TravelogueController {

private final TravelogueFacadeService travelogueFacadeService;

@Operation(description = "여행기 작성")
@PostMapping
public ResponseEntity<TravelogueResponse> createTravelogue(@Valid @RequestBody TravelogueRequest request) {
TravelogueResponse response = travelogueFacadeService.createTravelogue(request);

return ResponseEntity.created(URI.create("/api/v1/travelogues/" + response.id()))
.body(response);
}

@Operation(description = "여행기 상세 조회")
@GetMapping("/{id}")
public ResponseEntity<TravelogueResponse> findTravelogue(@Valid @PathVariable Long id) {
return ResponseEntity.ok(travelogueFacadeService.findTravelogueById(id));
}

@Operation(description = "여행기 메인 페이지 조회")
@PageableAsQueryParam
@GetMapping
public ResponseEntity<Page<TravelogueResponse>> findMainPageTravelogues(
@Parameter(hidden = true)
@PageableDefault(size = 5, sort = "id", direction = Direction.DESC)
Pageable pageable
) {
return ResponseEntity.ok(travelogueFacadeService.findTravelogues(pageable));
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package woowacourse.touroot.travelogue.domain.day.domain;
package woowacourse.touroot.travelogue.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
Expand All @@ -10,12 +10,13 @@
import jakarta.persistence.ManyToOne;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import woowacourse.touroot.entity.BaseEntity;
import woowacourse.touroot.travelogue.domain.Travelogue;

@Getter
@EqualsAndHashCode(of = "id", callSuper = false)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Entity
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package woowacourse.touroot.travelogue.domain.photo.domain;
package woowacourse.touroot.travelogue.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
Expand All @@ -13,7 +13,6 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import woowacourse.touroot.entity.BaseEntity;
import woowacourse.touroot.travelogue.domain.place.domain.TraveloguePlace;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand All @@ -35,7 +34,7 @@ public class TraveloguePhoto extends BaseEntity {
@ManyToOne(fetch = FetchType.LAZY)
private TraveloguePlace traveloguePlace;

public TraveloguePhoto(String key, Integer order, TraveloguePlace traveloguePlace) {
public TraveloguePhoto(Integer order, String key, TraveloguePlace traveloguePlace) {
this(null, key, order, traveloguePlace);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package woowacourse.touroot.travelogue.domain.place.domain;
package woowacourse.touroot.travelogue.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
Expand All @@ -14,7 +14,6 @@
import lombok.NoArgsConstructor;
import woowacourse.touroot.entity.BaseEntity;
import woowacourse.touroot.place.domain.Place;
import woowacourse.touroot.travelogue.domain.day.domain.TravelogueDay;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package woowacourse.touroot.travelogue.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import woowacourse.touroot.travelogue.domain.Travelogue;
import woowacourse.touroot.travelogue.domain.TravelogueDay;

public record TravelogueDayRequest(
@Schema(description = "여행기 장소 목록")
@NotNull(message = "여행기 장소 목록은 비어있을 수 없습니다.")
@Valid
List<TraveloguePlaceRequest> places
) {

public TravelogueDay toTravelogueDay(int order, Travelogue travelogue) {
return new TravelogueDay(order, travelogue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package woowacourse.touroot.travelogue.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;

public record TravelogueLocationRequest(
@Schema(description = "여행기 장소 위도", example = "37.5175896")
@NotNull(message = "여행기 장소 위도는 비어있을 수 없습니다.")
String lat,
@Schema(description = "여행기 장소 경도", example = "127.0867236")
@NotNull(message = "여행기 장소 경도는 비어있을 수 없습니다.")
String lng
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package woowacourse.touroot.travelogue.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import woowacourse.touroot.travelogue.domain.TraveloguePhoto;
import woowacourse.touroot.travelogue.domain.TraveloguePlace;

public record TraveloguePhotoRequest(
@Schema(description = "여행기 장소 사진 Key", example = "photo.png")
@NotNull(message = "여행기 장소 사진 Key 값은 비어있을 수 없습니다.")
String key
) {

public TraveloguePhoto toTraveloguePhoto(int order, TraveloguePlace traveloguePlace) {
return new TraveloguePhoto(order, key, traveloguePlace);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package woowacourse.touroot.travelogue.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import woowacourse.touroot.place.domain.Place;
import woowacourse.touroot.travelogue.domain.TravelogueDay;
import woowacourse.touroot.travelogue.domain.TraveloguePlace;

public record TraveloguePlaceRequest(
@Schema(description = "여행기 장소 이름", example = "선릉 캠퍼스")
@NotNull(message = "여행기 장소 이름은 비어있을 수 없습니다.")
String name,
@Schema(description = "여행기 장소 위치 정보")
@NotNull(message = "여행기 장소 위치 정보는 비어있을 수 없습니다.")
@Valid
TravelogueLocationRequest location,
@Schema(description = "여행기 장소 설명", example = "성담 빌딩에 위치한 선릉 캠퍼스입니다.")
String description,
@Schema(description = "여행기 장소 사진")
@NotNull(message = "여행기 장소 사진은 비어있을 수 없습니다.")
@Valid
List<TraveloguePhotoRequest> photos
) {

public TraveloguePlace toTraveloguePlace(int order, Place place, TravelogueDay travelogueDay) {
return new TraveloguePlace(order, description, place, travelogueDay);
}

public Place toPlace() {
return new Place(name, location.lat(), location.lng());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package woowacourse.touroot.travelogue.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import woowacourse.touroot.travelogue.domain.Travelogue;

public record TravelogueRequest(
@Schema(description = "여행기 제목", example = "서울 강남 여행기")
@NotNull(message = "여행기 제목은 비어있을 수 없습니다.")
String title,
@Schema(description = "여행기 섬네일", example = "https://thumbnail.png")
@NotNull(message = "여행기 섬네일은 비어있을 수 없습니다.")
String thumbnail,
@Schema(description = "여행기 일자 목록")
@NotNull(message = "여행기 일자 목록은 비어있을 수 없습니다.")
@Valid
List<TravelogueDayRequest> days
) {

public Travelogue toTravelogue() {
return new Travelogue(title, thumbnail);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package woowacourse.touroot.travelogue.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.Builder;
import woowacourse.touroot.travelogue.domain.TravelogueDay;

@Builder
public record TravelogueDayResponse(
@Schema(description = "여행기 일자 ID", example = "1")
Long id,
@Schema(description = "여행기 장소 목록")
List<TraveloguePlaceResponse> places
) {

public static TravelogueDayResponse of(TravelogueDay day, List<TraveloguePlaceResponse> places) {
return TravelogueDayResponse.builder()
.id(day.getId())
.places(places)
.build();
}
}
Loading

0 comments on commit 4de3070

Please sign in to comment.