-
Notifications
You must be signed in to change notification settings - Fork 240
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
[Step3] 즐겨찾기 기능 구현 리뷰 요청드립니다. #238
base: misudev
Are you sure you want to change the base?
Changes from all commits
d879286
834b05f
11b4618
31a3de0
2542087
844bcd5
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,50 @@ | ||
package nextstep.subway.applicaion; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import nextstep.member.application.MemberService; | ||
import nextstep.member.domain.LoginMember; | ||
import nextstep.member.domain.MemberRepository; | ||
import nextstep.subway.applicaion.dto.FavoriteRequest; | ||
import nextstep.subway.applicaion.dto.FavoriteResponse; | ||
import nextstep.subway.domain.Favorite; | ||
import nextstep.subway.domain.FavoriteRepository; | ||
import nextstep.subway.domain.Station; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Service | ||
public class FavoriteService { | ||
private final StationService stationService; | ||
private final PathService pathService; | ||
private final MemberRepository memberRepository; | ||
private final FavoriteRepository favoriteRepository; | ||
|
||
public FavoriteService(StationService stationService, PathService pathService, | ||
MemberRepository memberRepository, FavoriteRepository favoriteRepository) { | ||
this.stationService = stationService; | ||
this.pathService = pathService; | ||
this.memberRepository = memberRepository; | ||
this.favoriteRepository = favoriteRepository; | ||
} | ||
|
||
public FavoriteResponse createFavorite(FavoriteRequest favoriteRequest, Long memberId) { | ||
Station source = stationService.findById(favoriteRequest.getSource()); | ||
Station target = stationService.findById(favoriteRequest.getTarget()); | ||
pathService.findPath(source, target); | ||
Favorite favorite = favoriteRepository.save(Favorite.of(memberId, source, target)); | ||
return FavoriteResponse.from(favorite); | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
public List<FavoriteResponse> findFavorites(Long memberId) { | ||
List<Favorite> favorites = favoriteRepository.findAllByMemberId(memberId); | ||
return favorites.stream().map(FavoriteResponse::from).collect(Collectors.toList()); | ||
} | ||
|
||
public void deleteFavorite(Long favoriteId, Long memberId) { | ||
Favorite favorite = favoriteRepository.getById(favoriteId); | ||
favorite.hasPermission(memberId); | ||
favoriteRepository.delete(favorite); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,10 +22,14 @@ public PathService(LineService lineService, StationService stationService) { | |
public PathResponse findPath(Long source, Long target) { | ||
Station upStation = stationService.findById(source); | ||
Station downStation = stationService.findById(target); | ||
List<Line> lines = lineService.findLines(); | ||
SubwayMap subwayMap = new SubwayMap(lines); | ||
Path path = subwayMap.findPath(upStation, downStation); | ||
Path path = findPath(upStation, downStation); | ||
|
||
return PathResponse.of(path); | ||
} | ||
|
||
Path findPath(Station upStation, Station downStation) { | ||
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. 접근제어자를 생략하신 이유가 있으신가요? 😄 |
||
List<Line> lines = lineService.findLines(); | ||
SubwayMap subwayMap = new SubwayMap(lines); | ||
return subwayMap.findPath(upStation, downStation); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package nextstep.subway.applicaion.dto; | ||
|
||
public class FavoriteRequest { | ||
private Long source; | ||
private Long target; | ||
|
||
public FavoriteRequest(Long source, Long target) { | ||
this.source = source; | ||
this.target = target; | ||
} | ||
|
||
public Long getSource() { | ||
return source; | ||
} | ||
|
||
public Long getTarget() { | ||
return target; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package nextstep.subway.applicaion.dto; | ||
|
||
import nextstep.subway.domain.Favorite; | ||
|
||
public class FavoriteResponse { | ||
private Long id; | ||
private Long memberId; | ||
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. 요구사항에 memberId 는 없네요! |
||
private StationResponse source; | ||
private StationResponse target; | ||
|
||
private FavoriteResponse(Long id, Long memberId, | ||
StationResponse source, StationResponse target) { | ||
this.id = id; | ||
this.memberId = memberId; | ||
this.source = source; | ||
this.target = target; | ||
} | ||
|
||
public static FavoriteResponse from(Favorite favorite) { | ||
return new FavoriteResponse(favorite.getId(), favorite.getMemberId(), | ||
StationResponse.of(favorite.getSource()), StationResponse.of(favorite.getTarget())); | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public Long getMemberId() { | ||
return memberId; | ||
} | ||
|
||
public StationResponse getSource() { | ||
return source; | ||
} | ||
|
||
public StationResponse getTarget() { | ||
return target; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package nextstep.subway.domain; | ||
|
||
import javax.persistence.Column; | ||
import javax.persistence.Entity; | ||
import javax.persistence.GeneratedValue; | ||
import javax.persistence.GenerationType; | ||
import javax.persistence.Id; | ||
import javax.persistence.JoinColumn; | ||
import javax.persistence.ManyToOne; | ||
|
||
@Entity | ||
public class Favorite { | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
@Column(name = "member_id") | ||
private Long memberId; | ||
|
||
@JoinColumn(name = "source_id") | ||
@ManyToOne | ||
private Station source; | ||
|
||
@JoinColumn(name = "target_id") | ||
@ManyToOne | ||
private Station target; | ||
|
||
private Favorite(Long memberId, Station source, Station target) { | ||
this.memberId = memberId; | ||
this.source = source; | ||
this.target = target; | ||
} | ||
|
||
protected Favorite() { | ||
|
||
} | ||
|
||
public static Favorite of(Long memberId, Station source, Station target) { | ||
return new Favorite(memberId, source, target); | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public Long getMemberId() { | ||
return memberId; | ||
} | ||
|
||
public Station getSource() { | ||
return source; | ||
} | ||
|
||
public Station getTarget() { | ||
return target; | ||
} | ||
|
||
public boolean hasPermission(Long memberId) { | ||
return this.memberId.equals(memberId); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package nextstep.subway.domain; | ||
|
||
import java.util.List; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface FavoriteRepository extends JpaRepository<Favorite, Long> { | ||
List<Favorite> findAllByMemberId(Long memberId); | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,5 +1,6 @@ | ||||||||||||||||
package nextstep.subway.domain; | ||||||||||||||||
|
||||||||||||||||
import java.util.Optional; | ||||||||||||||||
import org.jgrapht.GraphPath; | ||||||||||||||||
import org.jgrapht.alg.shortestpath.DijkstraShortestPath; | ||||||||||||||||
import org.jgrapht.graph.SimpleDirectedWeightedGraph; | ||||||||||||||||
|
@@ -22,6 +23,11 @@ public Path findPath(Station source, Station target) { | |||||||||||||||
DijkstraShortestPath<Station, SectionEdge> dijkstraShortestPath = new DijkstraShortestPath<>(graph); | ||||||||||||||||
GraphPath<Station, SectionEdge> result = dijkstraShortestPath.getPath(source, target); | ||||||||||||||||
|
||||||||||||||||
Optional.ofNullable(result) | ||||||||||||||||
.orElseThrow(() -> { | ||||||||||||||||
throw new IllegalArgumentException("출발역과 도착역이 연결되어 있지 않습니다."); | ||||||||||||||||
}); | ||||||||||||||||
|
||||||||||||||||
Comment on lines
+26
to
+30
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. Optional 을 사용하신 이유가 있으신가요?
Suggested change
|
||||||||||||||||
List<Section> sections = result.getEdgeList().stream() | ||||||||||||||||
.map(it -> it.getSection()) | ||||||||||||||||
.collect(Collectors.toList()); | ||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package nextstep.subway.ui; | ||
|
||
import java.net.URI; | ||
import java.util.List; | ||
import nextstep.auth.authorization.AuthenticationPrincipal; | ||
import nextstep.member.domain.LoginMember; | ||
import nextstep.subway.applicaion.FavoriteService; | ||
import nextstep.subway.applicaion.dto.FavoriteRequest; | ||
import nextstep.subway.applicaion.dto.FavoriteResponse; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.DeleteMapping; | ||
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; | ||
|
||
@RestController | ||
@RequestMapping("/favorites") | ||
public class FavoriteController { | ||
|
||
private final FavoriteService favoriteService; | ||
|
||
public FavoriteController(FavoriteService favoriteService) { | ||
this.favoriteService = favoriteService; | ||
} | ||
|
||
@PostMapping | ||
public ResponseEntity<FavoriteResponse> createFavorite( | ||
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. |
||
@AuthenticationPrincipal LoginMember loginMember, | ||
@RequestBody FavoriteRequest favoriteRequest) { | ||
FavoriteResponse favoriteResponse = favoriteService.createFavorite(favoriteRequest, loginMember.getId()); | ||
return ResponseEntity.created(URI.create("/favorites/" + favoriteResponse.getId())).body(favoriteResponse); | ||
} | ||
|
||
@GetMapping | ||
public ResponseEntity<List<FavoriteResponse>> getFavorites(@AuthenticationPrincipal LoginMember loginMember) { | ||
List<FavoriteResponse> favoriteResponses = favoriteService.findFavorites(loginMember.getId()); | ||
return ResponseEntity.ok(favoriteResponses); | ||
} | ||
|
||
@DeleteMapping("/{favoriteId}") | ||
public ResponseEntity<Void> deleteFavorite(@AuthenticationPrincipal LoginMember loginMember, @PathVariable Long favoriteId) { | ||
favoriteService.deleteFavorite(favoriteId, loginMember.getId()); | ||
return ResponseEntity.noContent().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.
memberRepository 를 사용하고 있지 않는데요,
즐겨찾기 생성, 조회, 삭제 시 유요한 memberId 인지 확인하지 않아도 될까요? 😄