Skip to content

Commit

Permalink
Merge PR(#117) from feature/cache-#116 - 카테고리 조회 기능에 캐싱 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
woody35545 authored May 30, 2024
2 parents 1d89f58 + 6272228 commit 677d62d
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 24 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
</dependency>
<!-- Spring Cache -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/t3t/frontserver/FrontServerApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.cache.annotation.EnableCaching;

@EnableCaching
@ConfigurationPropertiesScan
@SpringBootApplication
public class FrontServerApplication {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.t3t.frontserver.book.model.response.BookDetailResponse;
import com.t3t.frontserver.category.client.CategoryApiClient;
import com.t3t.frontserver.category.response.CategoryTreeResponse;
import com.t3t.frontserver.category.service.CategoryService;
import com.t3t.frontserver.model.response.BaseResponse;
import com.t3t.frontserver.model.response.PageResponse;
import lombok.RequiredArgsConstructor;
Expand All @@ -23,13 +24,13 @@
@Controller
public class BookCategoryController {
private final BookCategoryApiClient bookCategoryApiClient;
private final CategoryApiClient categoryAdaptor;
private final CategoryService categoryService;

@GetMapping("/category/{categoryId}/books")
public String getBooksByCategoryId(Model model, @PathVariable Integer categoryId,
@RequestParam(value = "pageNo", defaultValue = "0", required = false) int pageNo) {

List<CategoryTreeResponse> categoryList = getDataFromCategoryAdaptor(1, 2);
List<CategoryTreeResponse> categoryList = categoryService.getCategoryTreeByDepth(1, 2);
PageResponse<BookDetailResponse> bookList = getDataFromBookCategoryAdaptor(categoryId, pageNo);

if (bookList != null) {
Expand All @@ -49,11 +50,6 @@ public String getBooksByCategoryId(Model model, @PathVariable Integer categoryId
return "main/page/search";
}

private List<CategoryTreeResponse> getDataFromCategoryAdaptor(Integer startDepth, Integer maxDepth ) {
ResponseEntity<BaseResponse<List<CategoryTreeResponse>>> categoriesResponse = categoryAdaptor.getCategoryTreeByDepth(startDepth, maxDepth);
return handleResponse(categoriesResponse);
}

private PageResponse<BookDetailResponse> getDataFromBookCategoryAdaptor(Integer categoryId, int pageNo) {
ResponseEntity<BaseResponse<PageResponse<BookDetailResponse>>> booksResponse = bookCategoryApiClient.getBooksByCategoryId(categoryId, pageNo);
return handleResponse(booksResponse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.t3t.frontserver.book.model.response.BookDetailResponse;
import com.t3t.frontserver.category.client.CategoryApiClient;
import com.t3t.frontserver.category.response.CategoryTreeResponse;
import com.t3t.frontserver.category.service.CategoryService;
import com.t3t.frontserver.index.OrderFormRequest;
import com.t3t.frontserver.model.response.BaseResponse;
import com.t3t.frontserver.model.response.PageResponse;
Expand All @@ -24,15 +25,15 @@
@Controller
@RequiredArgsConstructor
public class BookController {
private final CategoryApiClient categoryAdaptor;
private final BookApiClient bookApiClient;
private final ReviewApiClient reviewApiClient;
private final CategoryService categoryService;

@GetMapping("books/{bookId}")
public String getBook(Model model, @PathVariable Long bookId,
@RequestParam(value = "pageNo", defaultValue = "0", required = false) int pageNo) {

List<CategoryTreeResponse> categoryList = getDataFromCategoryAdaptor(1, 2);
List<CategoryTreeResponse> categoryList = categoryService.getCategoryTreeByDepth(1, 2);
BookDetailResponse bookDetailList = getDataFromBookAdaptor(bookId);
PageResponse<ReviewResponse> reviewList = getDataFromReviewAdaptor(bookId, pageNo);

Expand All @@ -58,11 +59,6 @@ public String getBook(Model model, @PathVariable Long bookId,
return "main/page/detail";
}

private List<CategoryTreeResponse> getDataFromCategoryAdaptor(Integer startDepth, Integer maxDepth ) {
ResponseEntity<BaseResponse<List<CategoryTreeResponse>>> categoriesResponse = categoryAdaptor.getCategoryTreeByDepth(startDepth, maxDepth);
return handleResponse(categoriesResponse);
}

private BookDetailResponse getDataFromBookAdaptor(Long bookId) {
ResponseEntity<BaseResponse<BookDetailResponse>> bookDetailResponse = bookApiClient.getBook(bookId);
return handleResponse(bookDetailResponse);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.t3t.frontserver.category.response;

import lombok.Builder;
import lombok.Data;
import lombok.*;

import java.util.List;

Expand All @@ -12,6 +11,8 @@
*/
@Data
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class CategoryTreeResponse {
private Integer categoryId;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,26 @@
import com.t3t.frontserver.category.adaptor.CategoryAdaptor;
import com.t3t.frontserver.category.response.CategoryTreeResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@CacheConfig(cacheNames = "categories")
@RequiredArgsConstructor
@Service
public class CategoryService {
private final CategoryAdaptor categoryAdaptor;

/**
* 카테고리 트리를 조회한다.
* 요청하는 startDepth 와 maxDepth 에 대해서 캐싱이 적용되어 조회된다.
*
* @author woody33545(구건모)
*/
@Cacheable(key = "'startDepth:' + #startDepth + 'maxDepth:' + #maxDepth", unless = "#result == null")
public List<CategoryTreeResponse> getCategoryTreeByDepth(Integer startDepth, Integer maxDepth) {
return categoryAdaptor.getCategoryTreeByDepth(startDepth, maxDepth);
}
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/com/t3t/frontserver/config/CacheConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.t3t.frontserver.config;

import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@Configuration
public class CacheConfig {

/**
* Cache Manager 빈 등록
* Global Cache 로 Redis 를 사용하므로 RedisCacheManager 로 설정한다.
* @author woody35545(구건모)
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration
.defaultCacheConfig()
.disableCachingNullValues()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
.entryTtl(Duration.ofMinutes(60L));

return RedisCacheManager.RedisCacheManagerBuilder
.fromConnectionFactory(redisConnectionFactory)
.cacheDefaults(redisCacheConfiguration)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.t3t.frontserver.category.client.CategoryApiClient;
import com.t3t.frontserver.category.response.CategoryTreeResponse;
import com.t3t.frontserver.category.service.CategoryService;
import com.t3t.frontserver.main.response.BookInfoBrief;
import com.t3t.frontserver.model.response.BaseResponse;
import com.t3t.frontserver.recommendation.client.RecommendationApiClient;
Expand All @@ -21,7 +22,7 @@
@RequiredArgsConstructor
public class MainController {
private final RecommendationApiClient recommendationAdaptor;
private final CategoryApiClient categoryAdaptor;
private final CategoryService categoryService;

@GetMapping("/")
public String homeView(Model model) {
Expand All @@ -32,7 +33,7 @@ public String homeView(Model model) {
LocalDate currentDate = LocalDate.now();
//String formattedDate = currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
String formattedDate = "2024-04-06"; // 테스트를 위해 값을 고정, 실제 배포시에는 삭제 예정
List<CategoryTreeResponse> categoryList = getDataFromCategoryAdaptor(1, 2);
List<CategoryTreeResponse> categoryList = categoryService.getCategoryTreeByDepth(1, 2);
List<BookInfoBrief> recentlyPublishedBookList = getDataFromRecommendationAdaptor(() -> recommendationAdaptor.getRecentlyPublishedBooks(formattedDate, defaultMaxCount));
List<BookInfoBrief> mostLikeBookList = getDataFromRecommendationAdaptor(() -> recommendationAdaptor.getBooksByMostLikedAndHighAverageScore(defaultMaxCount));
List<BookInfoBrief> bestSellerBookList = getDataFromRecommendationAdaptor(() -> recommendationAdaptor.getBestSellerBooks(defaultMaxCount));
Expand All @@ -46,11 +47,6 @@ public String homeView(Model model) {
return "main/page/home";
}

private List<CategoryTreeResponse> getDataFromCategoryAdaptor(Integer startDepth, Integer maxDepth ) {
ResponseEntity<BaseResponse<List<CategoryTreeResponse>>> categoriesResponse = categoryAdaptor.getCategoryTreeByDepth(startDepth, maxDepth);
return handleResponse(categoriesResponse);
}

private List<BookInfoBrief> getDataFromRecommendationAdaptor(Supplier<ResponseEntity<BaseResponse<List<BookInfoBrief>>>> requestSupplier) {
ResponseEntity<BaseResponse<List<BookInfoBrief>>> responseEntity = requestSupplier.get();
return handleResponse(responseEntity);
Expand Down

0 comments on commit 677d62d

Please sign in to comment.