Skip to content

Commit

Permalink
[FIX] 랭킹 정보에 링크 OG 태그 정보 추가 (#705)
Browse files Browse the repository at this point in the history
* refactor: 함수명 수정 (link --> url)

* refactor: 함수명 수정 (link --> url)

* feat: 랭킹 결과에 링크 정보 포함

* refactor: RankingRepository --> RankingApi 로 이름 변경
  • Loading branch information
kimminkyeu authored Dec 9, 2024
1 parent 7e03b39 commit b4aa9b9
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package techpick.api.application.ranking.controller;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -13,8 +16,13 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import techpick.api.infrastructure.ranking.RankingRepository;
import techpick.api.application.ranking.dto.LinkInfoWithViewCount;
import techpick.api.application.ranking.dto.RankingApiMapper;
import techpick.api.domain.link.exception.ApiLinkException;
import techpick.api.domain.link.service.LinkService;
import techpick.api.infrastructure.ranking.RankingApi;
import techpick.api.application.ranking.dto.RankingByViewCount;
import techpick.core.dto.UrlWithCount;

/**
* techpick-ranking 서버로 부터 데이터를 받아와 뿌려준다.
Expand All @@ -26,7 +34,9 @@
@Tag(name = "추천/소개 API", description = "링크, 픽 등에 대한 소개")
public class RankingApiController {

private final RankingRepository rankingRepository;
private final RankingApi rankingApi;
private final RankingApiMapper rankingApiMapper;
private final LinkService linkService;

/**
* 주별, 일별 조회 수를 기반 으로 추천 한다.
Expand Down Expand Up @@ -54,13 +64,33 @@ public ResponseEntity<RankingByViewCount> getSuggestionByViewCount(
var before30Days = currentDay.minusDays(30);

var dailyViewRanking = // 오늘 + 어제
rankingRepository.getLinkRankingByViewCount(before1Day, currentDay, LIMIT).getBody();
mapToLinkInfoRanking(rankingApi.getUrlRankingByViewCount(before1Day, currentDay, LIMIT).getBody());

var past7DaysViewRanking = // 일주일 전 ~ 어제
rankingRepository.getLinkRankingByViewCount(before7Days, before1Day, LIMIT).getBody();
mapToLinkInfoRanking(rankingApi.getUrlRankingByViewCount(before7Days, before1Day, LIMIT).getBody());

var past30DaysPickRanking = // 한달 전 ~ 어제
rankingRepository.getLinkRankingByPickedCount(before30Days, before1Day, LIMIT).getBody();
mapToLinkInfoRanking(
rankingApi.getUrlRankingByPickedCount(before30Days, before1Day, LIMIT).getBody());

var response = new RankingByViewCount(dailyViewRanking, past7DaysViewRanking, past30DaysPickRanking);
return ResponseEntity.ok(response);
}

private List<LinkInfoWithViewCount> mapToLinkInfoRanking(List<UrlWithCount> urlWithCountList) {
if (Objects.isNull(urlWithCountList)) {
return List.of(/* empty list */);
}
var result = new ArrayList<LinkInfoWithViewCount>();
for (UrlWithCount urlWithCount : urlWithCountList) {
try {
var linkInfo = linkService.getLinkInfo(urlWithCount.url());
var rankingInfo = rankingApiMapper.toRankingWithLinkInfo(urlWithCount, linkInfo);
result.add(rankingInfo);
} catch (ApiLinkException exception) {
log.error("[랭킹 획득 - 서버에 저장되지 않은 링크가 랭킹에 포함되어 있습니다! ={}", urlWithCount.url(), exception);
}
}
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package techpick.api.application.ranking.dto;

import jakarta.validation.constraints.NotNull;
import techpick.core.dto.UrlWithCount;

/**
* 랭킹 서버로 부터 얻은 URL 정보 {@link UrlWithCount} 에 Opengraph Tag를 추가한 DTO
*/
public record LinkInfoWithViewCount(
@NotNull String url,
String title,
String description,
String imageUrl,
Long count
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package techpick.api.application.ranking.dto;

import org.mapstruct.InjectionStrategy;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy;

import techpick.api.domain.link.dto.LinkInfo;
import techpick.core.dto.UrlWithCount;

@Mapper(
componentModel = "spring",
injectionStrategy = InjectionStrategy.CONSTRUCTOR,
unmappedTargetPolicy = ReportingPolicy.ERROR
)
public interface RankingApiMapper {

@Mapping(target = "url", source = "urlWithCount.url")
LinkInfoWithViewCount toRankingWithLinkInfo(UrlWithCount urlWithCount, LinkInfo linkInfo);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
import java.util.List;

import io.swagger.v3.oas.annotations.media.Schema;
import techpick.core.dto.UrlWithCount;

public record RankingByViewCount(
@Schema(description = "오늘 하루 동안 인기 있는 링크 Top 10")
List<UrlWithCount> dailyViewRanking,
List<LinkInfoWithViewCount> dailyViewRanking,

@Schema(description = "지난 7일동안 링크 조회 수 Top 10")
List<UrlWithCount> weeklyViewRanking,
List<LinkInfoWithViewCount> weeklyViewRanking,

@Schema(description = "지난 30일동안 링크가 픽된 횟수 Top 10")
List<UrlWithCount> monthlyPickRanking
List<LinkInfoWithViewCount> monthlyPickRanking
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import org.springframework.web.client.support.RestClientAdapter;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;

import techpick.api.infrastructure.ranking.RankingRepository;
import techpick.api.infrastructure.ranking.RankingApi;

/**
* 외부 서버와 통신하는 것을 Http Interface 방식으로 사용하기 위한 설정. <br>
Expand All @@ -20,10 +20,10 @@ public class HttpApiConfiguration {
private String rankingServerUrl;

@Bean
public RankingRepository rankingApi() {
public RankingApi rankingApi() {
var restClient = RestClient.create(rankingServerUrl);
var adapter = RestClientAdapter.create(restClient);
var proxy = HttpServiceProxyFactory.builderFor(adapter).build();
return proxy.createClient(RankingRepository.class);
return proxy.createClient(RankingApi.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import techpick.api.domain.link.dto.LinkMapper;
import techpick.api.domain.link.exception.ApiLinkException;
import techpick.api.domain.link.service.LinkService;
import techpick.api.domain.pick.dto.PickCommand;
import techpick.api.domain.pick.service.PickService;
import techpick.api.infrastructure.ranking.RankingRepository;
import techpick.api.infrastructure.ranking.RankingApi;
import techpick.core.dto.UrlWithCount;
import techpick.core.model.folder.Folder;
import techpick.core.model.folder.FolderRepository;
Expand All @@ -34,7 +32,7 @@ public class RankingBasedStrategy implements InitialFolderStrategy {
private static final Integer LOAD_LIMIT = 15;

private final FolderRepository folderRepository;
private final RankingRepository rankingRepository;
private final RankingApi rankingApi;
private final PickService pickService;
private final LinkService linkService;

Expand All @@ -44,8 +42,8 @@ public void initFolder(User user, Folder root) {
var currentDay = LocalDate.now();
var before1Day = currentDay.minusDays(1);
var before30Days = currentDay.minusDays(30);
var monthlyRanking = rankingRepository
.getLinkRankingByViewCount(before30Days, before1Day, LOAD_LIMIT)
var monthlyRanking = rankingApi
.getUrlRankingByViewCount(before30Days, before1Day, LOAD_LIMIT)
.getBody();
savePickFromRankingList(user.getId(), monthlyRanking, monthlyFolder.getId());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
* 랭킹 서버와 통신하기 위한 Http Interface. <br>
* 형식은 techpick-api 모듈의 컨트롤러와 일치합니다.
*/
public interface RankingRepository {
public interface RankingApi {

/**
* 조회수 기반 링크 랭킹
*/
@GetExchange("/ranking/link/view")
ResponseEntity<List<UrlWithCount>> getLinkRankingByViewCount(
ResponseEntity<List<UrlWithCount>> getUrlRankingByViewCount(
@RequestParam("date_begin") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate dateBegin,
@RequestParam("date_end") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate dateEnd,
@RequestParam(required = false, defaultValue = "5") Integer limit
Expand All @@ -31,7 +31,7 @@ ResponseEntity<List<UrlWithCount>> getLinkRankingByViewCount(
* 픽된 횟수 기반 링크 랭킹
*/
@GetExchange("/ranking/link/picked")
ResponseEntity<List<UrlWithCount>> getLinkRankingByPickedCount(
ResponseEntity<List<UrlWithCount>> getUrlRankingByPickedCount(
@RequestParam("date_begin") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate dateBegin,
@RequestParam("date_end") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate dateEnd,
@RequestParam(required = false, defaultValue = "5") Integer limit
Expand Down

0 comments on commit b4aa9b9

Please sign in to comment.