Skip to content

[#145] 좋아요 추가, 삭제 api 구현 #160

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

Merged
merged 7 commits into from
Apr 17, 2023
Merged

Conversation

youngjijang
Copy link
Collaborator

@youngjijang youngjijang commented Apr 16, 2023

🍀 목적

좋아요 추가, 삭제 api 구현

❓ pr 포인트

  • 자신의 책장은 좋아요 하지 못하게 하였습니다.
  • 이미 좋아요가 있는데 중복으로 좋아요 생성 요청시 예외가 발생하도록 하였는데 이미 존재할 경우 존재하던 것을 삭제하고 새로 저장을 해도 괜찮을 것 같아요(인스타 좋아요 처럼)
  • 일단 slice test만 진행된 상태여서 추가 api 구현시 통합테스트도 추가하겠습니다.

#145

@youngjijang youngjijang added 백엔드 백엔드 이슈 ✨ feat 새로운 기능에 추가에 대한 커밋 ✅ test 테스트 코드 수정에 대한 커밋 labels Apr 16, 2023
@youngjijang youngjijang requested review from devYSK and tinajeong April 16, 2023 14:02
@youngjijang youngjijang self-assigned this Apr 16, 2023
@github-actions
Copy link

github-actions bot commented Apr 16, 2023

Test Results

  57 files    57 suites   32s ⏱️
404 tests 404 ✔️ 0 💤 0
420 runs  420 ✔️ 0 💤 0

Results for commit 55c9dc6.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Apr 16, 2023

Jacoco Test Coverage Reports

File Coverage [99.17%] 🍏
BookshelfLike.java 100% 🍏
Bookshelf.java 100% 🍏
DefaultBookshelfLikeService.java 100% 🍏
BookshelfLikeController.java 100% 🍏
BookshelfLikeSupportImpl.java 94.29% 🍏
Total Project Coverage 88.9% 🍏

Comment on lines +27 to +54
* </Pre>
* @param bookshelfId
* @param userPrincipal
* @return status : ok
*/
@PostMapping()
@PreAuthorize(value = "hasAnyRole('ROLE_ADMIN', 'ROLE_USER')")
public ResponseEntity<Void> createLike(@PathVariable Long bookshelfId,
@AuthenticationPrincipal UserPrincipal userPrincipal) {
bookshelfLikeService.createBookshelfLike(userPrincipal.getUserId(), bookshelfId);
return ResponseEntity.ok().build();
}

/***
* <Pre>
* 책장 좋아요 해제
* </Pre>
* @param bookshelfId
* @param userPrincipal
* @return status : ok
*/
@DeleteMapping()
@PreAuthorize(value = "hasAnyRole('ROLE_ADMIN', 'ROLE_USER')")
public ResponseEntity<Void> deleteLike(@PathVariable Long bookshelfId,
@AuthenticationPrincipal UserPrincipal userPrincipal) {
bookshelfLikeService.deleteBookshelfLike(userPrincipal.getUserId(), bookshelfId);
return ResponseEntity.ok().build();
}
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.

집 컴퓨터와 폰으로 좋아요를 안 누른 상태의 같은 페이지를 열고 집 컴퓨터로만 좋아요를 눌렀다고 가정해볼게요.
해당 상태로 폰을 들고 밖으로 나가서 페이지를 본다면 해당 책장에 좋아요가 안눌려있겠죠?

이부분은 무슨 말씀일까요?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@youngjijang

같은 페이지를 다른 브라우저에서 보고 있을 때,

  • 집브라우저는 좋아요가 눌린상태
  • 모바일 브라우저는 좋아요가 안눌린상태,
    서로 다른 상태를 가지고있을 때 모바일 브라우저로 다시 좋아요를 누른다면
    프론트엔드와 백엔드는 어떤 액션을 취해야 하는지 생각을 여쭤본겁니다!

Comment on lines 14 to 22
@Override
public String getMessage() {
return super.getMessage();
}

@Override
public ErrorCode getErrorCode() {
return ALREADY_EXISTS_BOOKSHELF_LIKE;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

오버라이드는 굳이 필요 없어도 될것같아요!

Comment on lines 4 to 5

boolean existsByBookshelfIdAndUserId(Long bookshelfId, Long userId);
Copy link
Collaborator

Choose a reason for hiding this comment

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

existsLike? 비슷한 메소드 네임으로도 줄일 수 있을것 같아요

Comment on lines +59 to +61
@JsonManagedReference
@OneToMany(mappedBy = "bookshelf", cascade = CascadeType.PERSIST, orphanRemoval = true)
private final Set<BookshelfLike> bookshelfLikes = new HashSet<>();
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.

아직 이야기된것은 없으나 그럴거라 예상합니다. 책장 상세 조회 응답에 추가할 예정입니다.

Copy link
Collaborator

Choose a reason for hiding this comment

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

혹시 그렇다면

  • 매번 count 쿼리를 사용할것인지
  • 좋아요 수를 저장할 컬럼을 추가할것인지
    고민해보고 말씀해주세요!

Comment on lines 26 to 35

@Override
public void createBookshelfLike(Long userId, Long bookshelfId) {
User user = userService.getById(userId);
Bookshelf bookshelf = bookshelfService.getById(bookshelfId);
if (bookshelfLikeRepository.existsByBookshelfIdAndUserId(bookshelfId, userId)) {
throw new AlreadyExistsBookshelfLikeException(bookshelf.getId());
}
bookshelfLikeRepository.save(BookshelfLike.create(user, bookshelf));
}
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

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.

일단 그렇게 구현하였습니다. 프론트와 상의후에 덮어쓰기 형식으로 바꿀까 고민중입니다~

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

동시성 문제는 추후에 추가하겠습니다!

@@ -2,6 +2,8 @@ drop table if exists book_comments cascade;

drop table if exists bookshelf_item cascade;

drop table if exists bookshelf_likes cascade;
Copy link
Collaborator

Choose a reason for hiding this comment

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

good

Comment on lines +26 to +27
@ExtendWith(MockitoExtension.class)
class DefaultBookshelfLikeServiceTest {
Copy link
Collaborator

Choose a reason for hiding this comment

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

좋아요처럼 동시성 문제가 발생할 수 있는 로직은 통합테스트로 직접 DB에서 테스트해보는건 어떨까요?

Copy link
Collaborator

@devYSK devYSK left a comment

Choose a reason for hiding this comment

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

영지님 고생 많으셨습니다.
리뷰를 하면서 궁금한 점이 있어 적어놓았습니다. 특히 좋아요같은 기능은 동시성 문제가 발생하거나 서버의 상태값을 다루기 어려운 부분이라 생각됩니다. 한번 고민해보시는게 어떨까요?

@youngjijang
Copy link
Collaborator Author

PR 포인트에 남겨둔것과 같이 좋아요 재요청시에 인스타그램처럼 덮어쓰기를 할까 고민중입니다!
그렇게 되면 PUT 메소드로 변경하여 이미 존재할 경우에는 업데이트가 되겠죠?!
그부분은 재현님이과 상의후에 변경하도록 하겠습니다.
서버의 상태값을 다르기 어려운거는 어떤 경우일까요?

@youngjijang youngjijang merged commit 2cc1d12 into develop Apr 17, 2023
@youngjijang youngjijang deleted the bookshelf/likes branch May 1, 2023 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ feat 새로운 기능에 추가에 대한 커밋 ✅ test 테스트 코드 수정에 대한 커밋 백엔드 백엔드 이슈
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants