recommend
This commit is contained in:
@@ -2,19 +2,22 @@ package com.ktds.hi.recommend;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
|
||||
|
||||
/**
|
||||
* 추천 서비스 메인 애플리케이션
|
||||
* 추천 서비스 메인 애플리케이션 클래스
|
||||
* 가게 추천, 취향 분석 기능을 제공
|
||||
*
|
||||
* @author 하이오더 개발팀
|
||||
* @version 1.0.0
|
||||
*/
|
||||
@SpringBootApplication(scanBasePackages = {
|
||||
"com.ktds.hi.recommend",
|
||||
"com.ktds.hi.common"
|
||||
})
|
||||
@EnableFeignClients
|
||||
@EnableJpaAuditing
|
||||
public class RecommendServiceApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(RecommendServiceApplication.class, args);
|
||||
}
|
||||
|
||||
+80
-4
@@ -1,4 +1,80 @@
|
||||
package com.ktds.hi.recommend.infra.config;
|
||||
|
||||
public class RecommendWebClientConfig {
|
||||
}
|
||||
package com.ktds.hi.recommend.infra.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* 추천 서비스 WebClient 설정 클래스
|
||||
* 외부 서비스와의 HTTP 통신을 위한 설정
|
||||
*
|
||||
* @author 하이오더 개발팀
|
||||
* @version 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
public class RecommendWebClientConfig {
|
||||
|
||||
@Value("${services.store.url:http://store-service:8082}")
|
||||
private String storeServiceUrl;
|
||||
|
||||
@Value("${services.review.url:http://review-service:8083}")
|
||||
private String reviewServiceUrl;
|
||||
|
||||
@Value("${services.member.url:http://member-service:8081}")
|
||||
private String memberServiceUrl;
|
||||
|
||||
/**
|
||||
* 매장 서비스와 통신하기 위한 WebClient
|
||||
*/
|
||||
@Bean("storeWebClient")
|
||||
public WebClient storeWebClient() {
|
||||
return WebClient.builder()
|
||||
.baseUrl(storeServiceUrl)
|
||||
.codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(1024 * 1024))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 리뷰 서비스와 통신하기 위한 WebClient
|
||||
*/
|
||||
@Bean("reviewWebClient")
|
||||
public WebClient reviewWebClient() {
|
||||
return WebClient.builder()
|
||||
.baseUrl(reviewServiceUrl)
|
||||
.codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(1024 * 1024))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 회원 서비스와 통신하기 위한 WebClient
|
||||
*/
|
||||
@Bean("memberWebClient")
|
||||
public WebClient memberWebClient() {
|
||||
return WebClient.builder()
|
||||
.baseUrl(memberServiceUrl)
|
||||
.codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(1024 * 1024))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 일반적인 외부 API 호출을 위한 WebClient
|
||||
*/
|
||||
@Bean("externalWebClient")
|
||||
public WebClient externalWebClient() {
|
||||
return WebClient.builder()
|
||||
.codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(2 * 1024 * 1024))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 호환성을 위한 RestTemplate (레거시 지원)
|
||||
*/
|
||||
@Bean
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
}
|
||||
+150
-4
@@ -1,4 +1,150 @@
|
||||
package com.ktds.hi.recommend.infra.gateway;
|
||||
|
||||
public class ExternalServiceClient {
|
||||
}
|
||||
package com.ktds.hi.recommend.infra.gateway;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 외부 서비스 클라이언트
|
||||
* 다른 마이크로서비스와의 HTTP 통신을 담당
|
||||
*
|
||||
* @author 하이오더 개발팀
|
||||
* @version 1.0.0
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class ExternalServiceClient {
|
||||
|
||||
@Qualifier("storeWebClient")
|
||||
private final WebClient storeWebClient;
|
||||
|
||||
@Qualifier("reviewWebClient")
|
||||
private final WebClient reviewWebClient;
|
||||
|
||||
@Qualifier("memberWebClient")
|
||||
private final WebClient memberWebClient;
|
||||
|
||||
/**
|
||||
* 매장 정보 조회
|
||||
*/
|
||||
public Mono<Map<String, Object>> getStoreInfo(Long storeId) {
|
||||
return storeWebClient
|
||||
.get()
|
||||
.uri("/api/stores/{storeId}", storeId)
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {})
|
||||
.timeout(Duration.ofSeconds(5))
|
||||
.doOnError(error -> log.error("매장 정보 조회 실패: storeId={}, error={}", storeId, error.getMessage()))
|
||||
.onErrorReturn(Map.of());
|
||||
}
|
||||
|
||||
/**
|
||||
* 매장 목록 조회 (위치 기반)
|
||||
*/
|
||||
public Mono<List<Map<String, Object>>> getStoresByLocation(Double latitude, Double longitude, Integer radius) {
|
||||
return storeWebClient
|
||||
.get()
|
||||
.uri(uriBuilder -> uriBuilder
|
||||
.path("/api/stores/search")
|
||||
.queryParam("latitude", latitude)
|
||||
.queryParam("longitude", longitude)
|
||||
.queryParam("radius", radius)
|
||||
.build())
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<List<Map<String, Object>>>() {})
|
||||
.timeout(Duration.ofSeconds(10))
|
||||
.doOnError(error -> log.error("위치 기반 매장 조회 실패: lat={}, lng={}, radius={}, error={}",
|
||||
latitude, longitude, radius, error.getMessage()))
|
||||
.onErrorReturn(List.of());
|
||||
}
|
||||
|
||||
/**
|
||||
* 매장별 리뷰 조회
|
||||
*/
|
||||
public Mono<List<Map<String, Object>>> getStoreReviews(Long storeId, Integer limit) {
|
||||
return reviewWebClient
|
||||
.get()
|
||||
.uri(uriBuilder -> uriBuilder
|
||||
.path("/api/reviews/store/{storeId}")
|
||||
.queryParam("limit", limit)
|
||||
.build(storeId))
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<List<Map<String, Object>>>() {})
|
||||
.timeout(Duration.ofSeconds(5))
|
||||
.doOnError(error -> log.error("매장 리뷰 조회 실패: storeId={}, error={}", storeId, error.getMessage()))
|
||||
.onErrorReturn(List.of());
|
||||
}
|
||||
|
||||
/**
|
||||
* 회원 취향 정보 조회
|
||||
*/
|
||||
public Mono<Map<String, Object>> getMemberPreferences(Long memberId) {
|
||||
return memberWebClient
|
||||
.get()
|
||||
.uri("/api/members/{memberId}/preferences", memberId)
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {})
|
||||
.timeout(Duration.ofSeconds(5))
|
||||
.doOnError(error -> log.error("회원 취향 정보 조회 실패: memberId={}, error={}", memberId, error.getMessage()))
|
||||
.onErrorReturn(Map.of());
|
||||
}
|
||||
|
||||
/**
|
||||
* 회원 주문 이력 조회
|
||||
*/
|
||||
public Mono<List<Map<String, Object>>> getMemberOrderHistory(Long memberId, Integer limit) {
|
||||
return memberWebClient
|
||||
.get()
|
||||
.uri(uriBuilder -> uriBuilder
|
||||
.path("/api/members/{memberId}/orders")
|
||||
.queryParam("limit", limit)
|
||||
.build(memberId))
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<List<Map<String, Object>>>() {})
|
||||
.timeout(Duration.ofSeconds(5))
|
||||
.doOnError(error -> log.error("회원 주문 이력 조회 실패: memberId={}, error={}", memberId, error.getMessage()))
|
||||
.onErrorReturn(List.of());
|
||||
}
|
||||
|
||||
/**
|
||||
* 매장 평점 및 통계 조회
|
||||
*/
|
||||
public Mono<Map<String, Object>> getStoreStatistics(Long storeId) {
|
||||
return storeWebClient
|
||||
.get()
|
||||
.uri("/api/stores/{storeId}/statistics", storeId)
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {})
|
||||
.timeout(Duration.ofSeconds(5))
|
||||
.doOnError(error -> log.error("매장 통계 조회 실패: storeId={}, error={}", storeId, error.getMessage()))
|
||||
.onErrorReturn(Map.of("rating", 0.0, "reviewCount", 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* 인기 매장 조회
|
||||
*/
|
||||
public Mono<List<Map<String, Object>>> getPopularStores(String category, Integer limit) {
|
||||
return storeWebClient
|
||||
.get()
|
||||
.uri(uriBuilder -> uriBuilder
|
||||
.path("/api/stores/popular")
|
||||
.queryParam("category", category)
|
||||
.queryParam("limit", limit)
|
||||
.build())
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<List<Map<String, Object>>>() {})
|
||||
.timeout(Duration.ofSeconds(10))
|
||||
.doOnError(error -> log.error("인기 매장 조회 실패: category={}, limit={}, error={}",
|
||||
category, limit, error.getMessage()))
|
||||
.onErrorReturn(List.of());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user