본문 바로가기
💻 뚝딱뚝딱/북북클럽

[개발일지 #030] 좋아요(Like) 랭킹에서 피드 상세정보 함께 내려주기

by 뚜루리 2025. 5. 2.
728x90
320x100

🎯 오늘의 목표

  • 좋아요(Like) 랭킹에서 피드 상세정보 함께 내려주기

⚙️ 진행한 작업

  • 좋아요(Like) 랭킹에서 피드 상세정보 함께 내려주기

📌  현재 상황

https://ddururiiiiiii.tistory.com/652

 

[개발일지 #028] 좋아요 순 피드 조회 (주간/월간/연간/누적)

🎯 오늘의 목표좋아요 순 피드 조회 (주간/월간/연간/누적)⚙️ 진행한 작업좋아요 순 피드 조회 (주간/월간/연간/누적)📌 좋아요 순 피드 조회하는 방법1️⃣ DB 직접 카운트 + 정렬방식: SELECT *

ddururiiiiiii.tistory.com

  • 전의 개발일기를 보면 알수 있지만, 좋아요순 피드 조회를 Redis Sorted Set(ZSet)을 활용하여 구현하였음.
  • 즉, 레디스를 활용해서 좋아요순 조회를 하면 좋아요가 높은순부터 낮은순까지의 피드 ID만 반환받는데, 피드 ID만 보여주는 것은 좋아요순 피드 조회 기능에 의미가 없고 이 피드 ID를 활용하여 피드의 상세정보를 조회 해야 함.
  • 그래서 레디스를 활용하여 좋아요순 피드 ID를 반환받고 그 피드를 활용하여 피드들의 상세정보를 받아 내려주는 기능을 추가로 구현해보려 한다.

🛠️ 개발내용

📌  RankingFeedService.java 수정

package ddururi.bookbookclub.domain.feed.service;

/**
 * 피드 랭킹 서비스 (좋아요순, 조회수순 관리)
 */
@Service
@RequiredArgsConstructor
public class RankingFeedService {

    private final RedisTemplate<String, String> redisTemplate;
    private final FeedRepository feedRepository;

	//코드생략//

    public List<FeedResponse> getTopLikedFeedDetails(String period, int topN, Long userId) {
        String redisKey = getLikeKey(period);

        // 추가! Redis에서 ID + score(좋아요 수) 꺼내기
        Set<ZSetOperations.TypedTuple<String>> feedTuples = redisTemplate.opsForZSet()
                .reverseRangeWithScores(redisKey, 0, topN - 1);

        if (feedTuples == null || feedTuples.isEmpty()) return List.of();

        List<Long> topFeedIds = new ArrayList<>();
        Map<Long, Long> likeCountMap = new HashMap<>();

        for (ZSetOperations.TypedTuple<String> tuple : feedTuples) {
            Long feedId = Long.valueOf(tuple.getValue());
            Long likeCount = tuple.getScore().longValue();
            topFeedIds.add(feedId);
            likeCountMap.put(feedId, likeCount);
        }

        // DB에서 상세 조회
        List<Feed> feeds = feedRepository.findByIdInAndIsBlindedFalse(topFeedIds);
        Map<Long, Feed> feedMap = feeds.stream()
                .collect(Collectors.toMap(Feed::getId, f -> f));

        // 순서 + 좋아요 수 맞춰서 DTO로 변환
        return topFeedIds.stream()
                .map(feedId -> {
                    Feed feed = feedMap.get(feedId);
                    if (feed == null) return null;
                    Long likeCount = likeCountMap.getOrDefault(feedId, 0L);
                    return new FeedResponse(feed, likeCount, false);
                })
                .filter(Objects::nonNull)
                .toList();
    }
	
    //코드생략//

}

 

 

📌  FeedRepository.java 수정

package ddururi.bookbookclub.domain.feed.repository;

public interface FeedRepository extends JpaRepository<Feed, Long>{

    List<Feed> findByIdInAndIsBlindedFalse(List<Long> ids);

}

 

 

📌  FeedConotroller.java 수정

@GetMapping("/popular/like")
public ApiResponse<?> getPopularByLike(
        @RequestParam String period,
        @RequestParam(defaultValue = "10") int topN,
        @AuthenticationPrincipal CustomUserDetails userDetails) {

    List<FeedResponse> feedResponses = rankingFeedService.getTopLikedFeedDetails(
            period, topN, userDetails.getUser().getId());

    return ApiResponse.success(feedResponses);
}

 

 


[포스트맨으로 테스트하기]

GET /api/feeds/popular/like?period=weekly&topN=10

 

[테스트 결과 : 성공]

기존엔 피드 아이디만 반환했는데 피드와 관련된 정보를 함께 반환하고 있음.

728x90
320x100