From 82e5f99ae134d4bd8cab9a1e43eb234b13cc7183 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= <ohksj77@gmail.com>
Date: Sat, 13 Jul 2024 15:52:32 +0900
Subject: [PATCH] [FIX] change open api cache to use cacheput rather than
 cacheevict

---
 .../domain/friend/service/FriendService.java  |  8 ++---
 .../domain/group/service/GroupService.java    |  6 ++--
 .../domain/member/service/MemberService.java  |  6 ++--
 .../domain/path/service/PathService.java      |  6 ++--
 .../domain/place/service/PlaceService.java    |  4 +--
 .../domain/plan/service/PlanService.java      |  8 ++---
 backend/src/portfolio/REDIS_CACHE.md          | 29 ++++++++++++++++---
 7 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/backend/src/main/java/com/twtw/backend/domain/friend/service/FriendService.java b/backend/src/main/java/com/twtw/backend/domain/friend/service/FriendService.java
index ec605bcf..c6c1e1d3 100644
--- a/backend/src/main/java/com/twtw/backend/domain/friend/service/FriendService.java
+++ b/backend/src/main/java/com/twtw/backend/domain/friend/service/FriendService.java
@@ -21,7 +21,7 @@
 
 import lombok.RequiredArgsConstructor;
 
-import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -90,7 +90,7 @@ public String getMemberIdValue() {
         return authService.getMemberIdValue();
     }
 
-    @CacheEvict(
+    @CachePut(
             value = "getFriendsWithCache",
             key = "'getFriendsWithCache'.concat(#root.target.getMemberIdValue())",
             cacheManager = "cacheManager")
@@ -119,7 +119,7 @@ private List<FriendResponse> getFriendResponses() {
         return friendMapper.toResponses(friends);
     }
 
-    @CacheEvict(
+    @CachePut(
             value = "getFriendsByStatusWithCache",
             key =
                     "'getFriendsWithCache'.concat(#root.target.getMemberIdValue()).concat(#friendStatus.name())",
@@ -152,7 +152,7 @@ private List<FriendResponse> getFriendResponsesByStatus(final FriendStatus frien
         return friendMapper.toResponses(friends);
     }
 
-    @CacheEvict(
+    @CachePut(
             value = "getFriendsByNicknameWithCache",
             key = "'getFriendsWithCache'.concat(#root.target.getMemberIdValue()).concat(#nickname)",
             cacheManager = "cacheManager")
diff --git a/backend/src/main/java/com/twtw/backend/domain/group/service/GroupService.java b/backend/src/main/java/com/twtw/backend/domain/group/service/GroupService.java
index cff9ec5c..ba2c3b33 100644
--- a/backend/src/main/java/com/twtw/backend/domain/group/service/GroupService.java
+++ b/backend/src/main/java/com/twtw/backend/domain/group/service/GroupService.java
@@ -18,7 +18,7 @@
 import com.twtw.backend.global.constant.NotificationTitle;
 import com.twtw.backend.global.exception.EntityNotFoundException;
 
-import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -48,7 +48,7 @@ public GroupService(
         this.fcmProducer = fcmProducer;
     }
 
-    @CacheEvict(
+    @CachePut(
             value = "getGroupByIdWithCache",
             key = "'getGroupWithCache'.concat(#groupId)",
             cacheManager = "cacheManager")
@@ -152,7 +152,7 @@ public String getMemberIdValue() {
         return authService.getMemberIdValue();
     }
 
-    @CacheEvict(
+    @CachePut(
             value = "getMyGroupsWithCache",
             key = "'getMyGroupsWithCache'.concat(#root.target.getMemberIdValue())",
             cacheManager = "cacheManager")
diff --git a/backend/src/main/java/com/twtw/backend/domain/member/service/MemberService.java b/backend/src/main/java/com/twtw/backend/domain/member/service/MemberService.java
index 7b56d564..9e50223d 100644
--- a/backend/src/main/java/com/twtw/backend/domain/member/service/MemberService.java
+++ b/backend/src/main/java/com/twtw/backend/domain/member/service/MemberService.java
@@ -9,7 +9,7 @@
 import com.twtw.backend.global.exception.EntityNotFoundException;
 import com.twtw.backend.utils.QueryParseUtils;
 
-import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -44,7 +44,7 @@ public String getMemberIdValue() {
         return authService.getMemberIdValue();
     }
 
-    @CacheEvict(
+    @CachePut(
             value = "getMemberByNicknameWithCache",
             key = "'getMemberWithCache'.concat(#root.target.getMemberIdValue()).concat(#nickname)",
             cacheManager = "cacheManager")
@@ -94,7 +94,7 @@ public List<Member> getMembersByIds(final List<UUID> friendMemberIds) {
         return memberRepository.findAllByIds(friendMemberIds);
     }
 
-    @CacheEvict(
+    @CachePut(
             value = "getMemberByIdWithCache",
             key = "'getMemberByIdWithCache'.concat(#root.target.getMemberIdValue())",
             cacheManager = "cacheManager")
diff --git a/backend/src/main/java/com/twtw/backend/domain/path/service/PathService.java b/backend/src/main/java/com/twtw/backend/domain/path/service/PathService.java
index d6cf960c..42595f23 100644
--- a/backend/src/main/java/com/twtw/backend/domain/path/service/PathService.java
+++ b/backend/src/main/java/com/twtw/backend/domain/path/service/PathService.java
@@ -6,7 +6,7 @@
 import com.twtw.backend.domain.path.dto.client.ped.SearchPedPathResponse;
 import com.twtw.backend.global.client.MapClient;
 
-import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 
@@ -31,7 +31,7 @@ public SearchCarPathResponse searchCarPathWithCache(final SearchCarPathRequest r
         return carPathClient.request(request);
     }
 
-    @CacheEvict(
+    @CachePut(
             value = "carPath",
             key = "'searchCarPath'.concat(#request.toString())",
             cacheManager = "cacheManager")
@@ -48,7 +48,7 @@ public SearchPedPathResponse searchPedPathWithCache(final SearchPedPathRequest r
         return pedPathClient.request(request);
     }
 
-    @CacheEvict(
+    @CachePut(
             value = "pedPath",
             key = "'searchPedPath'.concat(#request.toString())",
             cacheManager = "cacheManager")
diff --git a/backend/src/main/java/com/twtw/backend/domain/place/service/PlaceService.java b/backend/src/main/java/com/twtw/backend/domain/place/service/PlaceService.java
index 52e67bff..0e0df563 100644
--- a/backend/src/main/java/com/twtw/backend/domain/place/service/PlaceService.java
+++ b/backend/src/main/java/com/twtw/backend/domain/place/service/PlaceService.java
@@ -10,7 +10,7 @@
 
 import lombok.RequiredArgsConstructor;
 
-import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 
@@ -20,7 +20,7 @@ public class PlaceService {
     private final PlaceMapper placeMapper;
     private final KakaoMapClient<SurroundPlaceRequest, SurroundPlaceResponse> surroundPlaceClient;
 
-    @CacheEvict(
+    @CachePut(
             value = "surroundPlace",
             key = "'searchSurroundPlace'.concat(#surroundPlaceRequest.toString())",
             cacheManager = "cacheManager")
diff --git a/backend/src/main/java/com/twtw/backend/domain/plan/service/PlanService.java b/backend/src/main/java/com/twtw/backend/domain/plan/service/PlanService.java
index 3b2a3d15..53fed51d 100644
--- a/backend/src/main/java/com/twtw/backend/domain/plan/service/PlanService.java
+++ b/backend/src/main/java/com/twtw/backend/domain/plan/service/PlanService.java
@@ -32,7 +32,7 @@
 
 import lombok.RequiredArgsConstructor;
 
-import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -124,7 +124,7 @@ public void outPlan(PlanMemberRequest request) {
         plan.deleteMember(member);
     }
 
-    @CacheEvict(
+    @CachePut(
             value = "getPlanByIdWithCache",
             key = "'getPlanByIdWithCache'.concat(#id)",
             cacheManager = "cacheManager")
@@ -171,7 +171,7 @@ public String getMemberIdValue() {
         return authService.getMemberIdValue();
     }
 
-    @CacheEvict(
+    @CachePut(
             value = "getPlansWithCache",
             key = "'getPlansWithCache'.concat(#root.target.getMemberIdValue())",
             cacheManager = "cacheManager")
@@ -243,7 +243,7 @@ public void deleteInvite(final PlanMemberRequest request) {
         plan.deleteInvite(member);
     }
 
-    @CacheEvict(
+    @CachePut(
             value = "getPlansByGroupIdWithCache",
             key = "'getPlansByGroupIdWithCache'.concat(#groupId)",
             cacheManager = "cacheManager")
diff --git a/backend/src/portfolio/REDIS_CACHE.md b/backend/src/portfolio/REDIS_CACHE.md
index 335097e2..4e5e9eb0 100644
--- a/backend/src/portfolio/REDIS_CACHE.md
+++ b/backend/src/portfolio/REDIS_CACHE.md
@@ -8,8 +8,9 @@
 
 ---
 
-> 사용자에게 경로를 제공하기 위해 Kakao, Naver,  Tmap Open API를 사용한다. 위 API 제공에 있어 호출까지의 **시간이 소요**되고 **비용 낭비**가 발생
+> 사용자에게 경로를 제공하기 위해 Kakao, Naver, Tmap Open API를 사용한다. 위 API 제공에 있어 호출까지의 **시간이 소요**되고 **비용 낭비**가 발생
 >
+
 - 이미 반환된 경로를 사용자가 재사용하는 경우가 많기 때문에 경로를 임시 메모리에 저장하는 로직 필요
 - ‘경로’라는 데이터 특성 상 한번 참조된 값에 대해 변경이 자주 일어나지 않음
 
@@ -19,18 +20,38 @@
 
 ### 적용
 
-- @CacheEvict와 @Cacheable Annotation을 사용하여 API에 레디스 캐시 적용
+- @CachePut과 @Cacheable Annotation을 사용하여 API에 레디스 캐시 적용
 
 ### 시퀀스 다이어그램
 
 ![image](https://github.com/HongDam-org/TWTW/assets/84346055/6cb63e15-767d-4a21-89cc-91724323f0b0)
 
-![image](https://github.com/HongDam-org/TWTW/assets/84346055/3375f917-e88e-480a-a3f1-bbcbd401557d)
+```Java
+
+@CachePut(
+        value = "surroundPlace",
+        key = "'searchSurroundPlace'.concat(#surroundPlaceRequest.toString())",
+        cacheManager = "cacheManager")
+public PlaceResponse searchSurroundPlace(final SurroundPlaceRequest surroundPlaceRequest) {
+    return getPlaceResponse(surroundPlaceRequest);
+}
+
+@Cacheable(
+        value = "surroundPlace",
+        key = "'searchSurroundPlace'.concat(#surroundPlaceRequest.toString())",
+        cacheManager = "cacheManager",
+        unless = "#result.results.size() <= 0")
+public PlaceResponse searchSurroundPlaceWithCache(
+        final SurroundPlaceRequest surroundPlaceRequest) {
+    return getPlaceResponse(surroundPlaceRequest);
+}
+```
 
 ### 시나리오
 
 > Redis Cache를 적용하였을 때 성능 분석을 위해 다음과 같은 시나리오를 세우고 테스트 진행
 >
+
 1. 회원가입 수행
 2. 보행자 경로 API를 요청하여 수행
 
@@ -56,4 +77,4 @@
 
 1. Redis Cache를 사용할 경우 사용하지 않은 경우에 비해 4.12배의 속도 성능 향상
 2. Open API를 중복 요청하지 않아 네트워크 비용 절감
-3. CacheEvict를 통해 사용자의 요청 경로가 변경된 경우 기존 Cache값을 삭제하고 변경된 경로를 저장하고 제공하여 서비스상 유연성 향상
+3. CachePut를 통해 사용자의 요청 경로가 변경된 경우 기존 Cache값을 삭제하고 변경된 경로를 저장하고 제공하여 서비스상 유연성 향상