프로젝트 (Java)/예약마켓

[프로젝트] 17. 게시물 좋아요 기능

hihyuk 2024. 1. 26. 10:06

PostController 수정

PostController에 좋아요 토글 기능을 위한 엔드포인트를 추가합니다. 사용자 ID는 토큰 컨텍스트에서 추출합니다.

    @PutMapping("/like/{post_id}")
    public void likePost(@PathVariable("post_id") Long postId) {
        TokenContext context = TokenContextHolder.getContext();
        Long userId = context.getUserId();
        postService.likePost(userId, postId);
    }

 

Like 엔티티 수정

Like 엔티티의 setPost 메소드는 게시물에 좋아요를 추가하거나 제거할 때 사용됩니다. 이 메소드는 양방향 관계를 관리합니다.

    public void setPost(Post post) {
        if (this.post != null) {
            this.post.getLikes().remove(this);
        }
        this.post = post;

        if (!post.getLikes().contains(this)) {
            post.getLikes().add(this);
        }
    }

 

Post 엔티티 수정

Post 엔티티는 addLikeremoveLike 메소드를 통해 좋아요를 추가하고 제거하는 로직을 관리합니다.

    public void addLike(Like like) {
        this.likes.add(like);
        if(like.getPost() != this) {
            like.setPost(this);
        }
    }

    public void removeLike(Like like) {
        Iterator<Like> iterator = this.likes.iterator();
        while (iterator.hasNext()) {
            Like e = iterator.next();
            if (like.equals(e)) {
                iterator.remove();
            }
        }
    }

 

PostService 수정

PostService에서는 좋아요 토글 로직을 구현합니다. 이미 좋아요를 한 경우에는 좋아요를 취소하고, 그렇지 않은 경우에는 좋아요를 추가합니다.

    @Transactional
    public void likePost(Long userId, Long postId) {
        Post post = postRepository.findById(postId).orElseThrow(
                () -> new BadRequestException("존재하지 않는 게시물입니다.")
        );

        boolean alreadyLike = post.getLikes()
                .stream()
                .map(Like::getUserId)
                .anyMatch(uid -> uid == userId);

        if (alreadyLike) { // 이미 좋아요 했다면 취소
            Map<Long, Like> likes = post.getLikes()
                    .stream()
                    .collect(Collectors.toMap(Like::getUserId, Function.identity()));
            post.removeLike(likes.get(userId));
        }
        else { // 좋아요
            post.addLike(Like.builder().userId(userId).build());
        }
    }

 

결론

이 구현을 통해 사용자는 게시물에 대한 좋아요를 토글할 수 있게 됩니다. 사용자가 좋아요를 토글할 때마다 해당 게시물의 좋아요 수가 업데이트되며, 이는 게시물의 인기도를 나타내는 중요한 지표가 됩니다. 좋아요 기능은 사용자 경험을 향상시키며, 애플리케이션의 상호작용성을 높이는 데 기여합니다.