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] 북마크 컨트롤러 구현 및 TransportType Enum 리팩토링 #86

Merged
merged 7 commits into from
Aug 18, 2024
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package com.talkka.server.bookmark.controller;

import java.util.List;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.talkka.server.bookmark.dto.BookmarkReqDto;
import com.talkka.server.bookmark.dto.BookmarkRespDto;
import com.talkka.server.bookmark.exception.BookmarkNotFoundException;
import com.talkka.server.bookmark.exception.BookmarkUserNotFoundException;
import com.talkka.server.bookmark.exception.enums.InvalidTransportTypeEnumException;
import com.talkka.server.bookmark.service.BookmarkService;
import com.talkka.server.oauth.domain.OAuth2UserInfo;
import com.talkka.server.review.exception.ContentAccessException;

import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@RequestMapping("/bookmark")
public class BookmarkController {
private final BookmarkService bookmarkService;

// 본인이 작성한 북마크 리스트만 조회
@GetMapping("")
public ResponseEntity<?> getBookmarkList(@AuthenticationPrincipal OAuth2UserInfo oAuth2UserInfo) {
List<BookmarkRespDto> bookmarks = bookmarkService.getByUserId(oAuth2UserInfo.getUserId());
return ResponseEntity.ok(bookmarks);
}

@GetMapping("/{bookmarkId}")
public ResponseEntity<?> getBookmark(@AuthenticationPrincipal OAuth2UserInfo oAuth2UserInfo,
@PathVariable Long bookmarkId) {
Comment on lines +41 to +42
Copy link
Collaborator

Choose a reason for hiding this comment

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

북마크를 한개만 불러와서 사용하는 경우가 언제라고 생각하면 될까요?

현재 코드 상으로는 북마크와 연관관계로 묶여서 디테일까지 getBookmarkList 메서드에서 한번에 조회되는 것으로 보여지는데
따로 북마크 1개만의 정보가 필요한 상황이 생각나지 않아 질문 드립니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

북마크를 수정할때, 수정하려는 북마크 정보만 조회해야한다고 생각해 추가했습니다.

Copy link
Collaborator

Choose a reason for hiding this comment

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

수정할 때 이미 불러와진 정보들을 활용해서 할 수는 없는걸까요?(아직 JPA를 잘 몰라서...)

Copy link
Contributor

Choose a reason for hiding this comment

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

bookmark id 를 bookmarkresp 에서 넘긴다면 하나 단위의 조회는 잘 쓰지 않을 것 같긴합니다.
근데 크게 신경 안써도 될듯.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

일단 남겨두고 이후 프론트 구현시에도 사용하지 않으면 삭제하도록 하겠습니다.

ResponseEntity<?> response;
try {
BookmarkRespDto bookmark = bookmarkService.getByBookmarkId(oAuth2UserInfo.getUserId(), bookmarkId);
response = ResponseEntity.ok(bookmark);
} catch (BookmarkNotFoundException | BookmarkUserNotFoundException exception) {
response = ResponseEntity.badRequest().body(exception.getMessage());
} catch (ContentAccessException exception) {
response = ResponseEntity.status(HttpStatus.FORBIDDEN).body(exception.getMessage());
}
return response;
}

@PostMapping("")
public ResponseEntity<?> createBookmark(@AuthenticationPrincipal OAuth2UserInfo oAuth2UserInfo,
BookmarkReqDto bookmarkReqDto) {
ResponseEntity<?> response;
try {
BookmarkRespDto bookmark = bookmarkService.createBookmark(bookmarkReqDto, oAuth2UserInfo.getUserId());
return ResponseEntity.ok(bookmark);
} catch (BookmarkUserNotFoundException | InvalidTransportTypeEnumException exception) {
response = ResponseEntity.badRequest().body(exception.getMessage());
}
return response;
}

@PutMapping("{bookmarkId}")
public ResponseEntity<?> updateBookmark(@AuthenticationPrincipal OAuth2UserInfo oAuth2UserInfo,
BookmarkReqDto bookmarkReqDto, @PathVariable Long bookmarkId) {
ResponseEntity<?> response;
Copy link
Collaborator

Choose a reason for hiding this comment

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

해당 어노테이션은 어떤 의미일까요?
잠깐 찾아보니 컴파일러 경고에 대해서 처리하는 것으로 보여지는데 설명 한번 부탁드립니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

방금 path 수정하면서 잘못들어간 어노테이션임을 확인했고 삭제했습니다.

try {
BookmarkRespDto bookmark = bookmarkService.updateBookmark(bookmarkReqDto, oAuth2UserInfo.getUserId(),
bookmarkId);
response = ResponseEntity.ok(bookmark);
} catch (BookmarkNotFoundException | BookmarkUserNotFoundException
| InvalidTransportTypeEnumException exception) {
response = ResponseEntity.badRequest().body(exception.getMessage());
} catch (ContentAccessException exception) {
response = ResponseEntity.status(HttpStatus.FORBIDDEN).body(exception.getMessage());
}
return response;
}

@DeleteMapping("/{bookmarkId}")
public ResponseEntity<?> deleteBookmark(@AuthenticationPrincipal OAuth2UserInfo oAuth2UserInfo,
@PathVariable Long bookmarkId) {
ResponseEntity<?> response;
try {
bookmarkService.deleteBookmark(oAuth2UserInfo.getUserId(), bookmarkId);
response = ResponseEntity.ok().build();
} catch (BookmarkNotFoundException | BookmarkUserNotFoundException exception) {
response = ResponseEntity.badRequest().body(exception.getMessage());
} catch (ContentAccessException exception) {
response = ResponseEntity.status(HttpStatus.FORBIDDEN).body(exception.getMessage());
}
return response;
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package com.talkka.server.bookmark.dto;

import com.talkka.server.bookmark.dao.BookmarkDetailEntity;
import com.talkka.server.bookmark.enums.TransportType;
import com.talkka.server.subway.enums.Updown;

public record BookmarkDetailRespDto(
Integer seq,
String type,
TransportType type,
Long subwayStationId,
Updown subwayUpdown,
Long busRouteStationId
) {
public static BookmarkDetailRespDto of(BookmarkDetailEntity entity) {
return new BookmarkDetailRespDto(
entity.getSeq(),
entity.getType().getType(),
entity.getType(),
entity.getSubwayStationId(),
entity.getSubwayUpdown(),
entity.getBusRouteStationId()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@

@Getter
public enum TransportType {
BUS("bus"), SUBWAY("subway");
BUS, SUBWAY;

private final String type;

TransportType(String type) {
this.type = type;
TransportType() {
}

public static TransportType valueOfEnumString(String enumValue) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.talkka.server.bookmark.dto.BookmarkRespDto;
import com.talkka.server.bookmark.exception.BookmarkNotFoundException;
import com.talkka.server.bookmark.exception.BookmarkUserNotFoundException;
import com.talkka.server.bookmark.exception.enums.InvalidTransportTypeEnumException;
import com.talkka.server.common.validator.ContentAccessValidator;
import com.talkka.server.review.exception.ContentAccessException;
import com.talkka.server.user.dao.UserEntity;
Expand All @@ -27,18 +28,14 @@ public class BookmarkService {
private final UserRepository userRepository;
private final ContentAccessValidator contentAccessValidator;

@Transactional
public BookmarkRespDto createBookmark(BookmarkReqDto dto, Long userId) throws BookmarkUserNotFoundException {
public BookmarkRespDto getByBookmarkId(Long userId, Long bookmarkId) throws
Copy link
Contributor

Choose a reason for hiding this comment

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

getBookmarkById가 조금 더 좋은 표현이라고 생각합니다. 현재 표현은 ID 를 가져오는 것 같습니다.

BookmarkNotFoundException,
Copy link
Contributor

Choose a reason for hiding this comment

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

ContentAccessException 도 명시했으면 합니다.

BookmarkUserNotFoundException {
// 본인이 작성한 북마크만 조회 하도록 변경
UserEntity user = userRepository.findById(userId).orElseThrow(BookmarkUserNotFoundException::new);
BookmarkEntity bookmark = dto.toEntity(user);
dto.details().stream()
.map(detail -> detail.toEntity(bookmark))
.forEach(bookmark.getDetails()::add);
return BookmarkRespDto.of(bookmarkRepository.save(bookmark));
}

public BookmarkRespDto getByBookmarkId(Long id) throws BookmarkNotFoundException {
BookmarkEntity bookmark = bookmarkRepository.findById(id).orElseThrow(BookmarkUserNotFoundException::new);
BookmarkEntity bookmark = bookmarkRepository.findById(bookmarkId)
.orElseThrow(BookmarkUserNotFoundException::new);
contentAccessValidator.validateOwnerContentAccess(userId, user.getGrade(), bookmark.getUser().getId());
return BookmarkRespDto.of(bookmark);
}

Expand All @@ -49,17 +46,29 @@ public List<BookmarkRespDto> getByUserId(Long userId) {
}

@Transactional
public BookmarkRespDto updateBookmark(BookmarkReqDto dto, Long bookmarkId, Long userId) throws
public BookmarkRespDto createBookmark(BookmarkReqDto dto, Long userId) throws BookmarkUserNotFoundException,
InvalidTransportTypeEnumException {
UserEntity user = userRepository.findById(userId).orElseThrow(BookmarkUserNotFoundException::new);
BookmarkEntity bookmark = dto.toEntity(user);
dto.details().stream()
.map(detail -> detail.toEntity(bookmark))
.forEach(bookmark.getDetails()::add);
return BookmarkRespDto.of(bookmarkRepository.save(bookmark));
}

@Transactional
public BookmarkRespDto updateBookmark(BookmarkReqDto dto, Long userId, Long bookmarkId) throws
BookmarkUserNotFoundException,
BookmarkNotFoundException,
InvalidTransportTypeEnumException,
ContentAccessException {

UserEntity user = userRepository.findById(userId).orElseThrow(BookmarkUserNotFoundException::new);
BookmarkEntity bookmark = bookmarkRepository.findById(bookmarkId)
.orElseThrow(BookmarkUserNotFoundException::new);
.orElseThrow(BookmarkNotFoundException::new);

// 작성자거나 관리자가 아니면 ContentAccessException 발생
contentAccessValidator.validateOwnerContentAccess(user.getId(), user.getGrade(), bookmark.getId());
contentAccessValidator.validateOwnerContentAccess(user.getId(), user.getGrade(), bookmark.getUser().getId());

// 기존 북마크 상세를 전부 지우고 전체를 새로 저장함
bookmarkDetailRepository.deleteByBookmarkId(bookmarkId);
Expand All @@ -69,7 +78,7 @@ public BookmarkRespDto updateBookmark(BookmarkReqDto dto, Long bookmarkId, Long
}

@Transactional
public Long deleteBookmark(Long bookmarkId, Long userId) throws
public Long deleteBookmark(Long userId, Long bookmarkId) throws
BookmarkUserNotFoundException,
BookmarkNotFoundException {

Expand Down
Loading