Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#54] 상품 조회 시 정렬/필터 POST 방식으로 수정 #60

Merged
merged 11 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,21 @@
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.example.moduleapi.controller.request.product.ProductSaveRequest;
import com.example.moduleapi.controller.request.product.ProductUpdateRequest;
import com.example.moduleapi.controller.response.PagingResponse;
import com.example.moduleapi.controller.response.product.ProductFindResponse;
import com.example.moduleapi.controller.response.product.ProductLikeResponse;
import com.example.moduleapi.controller.response.product.ProductResponse;
import com.example.moduleapi.service.product.ProductFacade;
import com.example.moduledomain.domain.product.OrderBy;
import com.example.moduledomain.domain.product.ProductCondition;
import com.example.moduledomain.domain.user.CustomUserDetails;
import com.example.moduledomain.request.ProductFilterRequest;
import com.example.moduledomain.response.ProductFindResponse;

@RestController
@RequestMapping("/api/v1/products")
Expand All @@ -48,16 +47,11 @@ public ProductFindResponse findById(@PathVariable Long id) {
return productFacade.findById(id);
}

@GetMapping
@PostMapping("/_search")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요거 _는 왜 들어간거에요 ?

Copy link
Collaborator Author

@JIWON27 JIWON27 Jan 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조회와 POST 조회를 구분짓기위해 _추가했는데... 불필요한 부분이면 수정하겠습니다!

public PagingResponse<ProductFindResponse> findProductsByCriteriaWithRecommendations(
@AuthenticationPrincipal CustomUserDetails customUserDetails,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "productCondition", required = false) ProductCondition productCondition,
@RequestParam(value = "pageNo", defaultValue = "0", required = false) int pageNo,
@RequestParam(value = "pageSize", defaultValue = DEFAULT_SIZE, required = false) int pageSize,
@RequestParam(value = "orderBy", required = false) OrderBy order) {
return productFacade.findProductsByCriteriaWithRecommendations(customUserDetails, keyword, productCondition,
pageNo, pageSize, order);
@AuthenticationPrincipal CustomUserDetails user,
@RequestBody ProductFilterRequest productFilterRequest) {
return productFacade.findProductsByCriteriaWithRecommendations(user.getUser(), productFilterRequest);
}

@PutMapping("/{id}")
Expand All @@ -83,7 +77,7 @@ public ProductLikeResponse productLike(@AuthenticationPrincipal CustomUserDetail

@DeleteMapping("/{id}/likes")
public ProductLikeResponse productLikeDelete(@AuthenticationPrincipal CustomUserDetails user,
@PathVariable Long id) {
@PathVariable Long id) {
return productFacade.productLikeDelete(user.getUser(), id);
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import com.example.moduleapi.controller.request.auction.BidRequest;
import com.example.moduleapi.controller.request.point.PointAmount;
import com.example.moduleapi.controller.response.auction.BidResponse;
import com.example.moduleapi.controller.response.product.ProductFindResponse;
import com.example.moduleapi.exception.auction.BiddingFailException;
import com.example.moduleapi.exception.auction.RedisLockAcquisitionException;
import com.example.moduleapi.exception.auction.RedisLockInterruptedException;
Expand All @@ -24,6 +23,7 @@
import com.example.moduledomain.domain.user.CustomUserDetails;
import com.example.moduledomain.domain.user.Gender;
import com.example.moduledomain.domain.user.User;
import com.example.moduledomain.response.ProductFindResponse;

@Service
public class AuctionService {
Expand All @@ -35,9 +35,12 @@ public class AuctionService {
private final BidLoggingService bidLoggingService;
private final PointService pointService;

public AuctionService(ProductFacade productFacade, HighestBidSseNotificationService bidSseNotificationService,
RedissonClient redissonClient, KafkaProducerService kafkaProducerService, BidLoggingService bidLoggingService,
PointService pointService) {
public AuctionService(ProductFacade productFacade,
HighestBidSseNotificationService bidSseNotificationService,
RedissonClient redissonClient,
KafkaProducerService kafkaProducerService,
BidLoggingService bidLoggingService,
PointService pointService) {
this.productFacade = productFacade;
this.bidSseNotificationService = bidSseNotificationService;
this.redissonClient = redissonClient;
Expand All @@ -60,7 +63,7 @@ public BidResponse biddingPrice(CustomUserDetails user, BidRequest bidRequest, L
currentHighestPrice = processBid(user, bidRequest, productId);
kafkaProducerService.publishAuctionPriceChangeNotification(productId, currentHighestPrice);
bidSseNotificationService.sendToAllUsers(productId, "최고가가 " + currentHighestPrice + "원으로 올랐습니다.",
"최고가 수정 알림");
"최고가 수정 알림");
} catch (InterruptedException e) {
throw new RedisLockInterruptedException(productId, e);
} finally {
Expand All @@ -70,7 +73,7 @@ public BidResponse biddingPrice(CustomUserDetails user, BidRequest bidRequest, L
}

return BidResponse.from(productId,
calculateIncreaseRate(productId, currentHighestPrice, bidRequest.getBiddingPrice()));
calculateIncreaseRate(productId, currentHighestPrice, bidRequest.getBiddingPrice()));
}

@Transactional
Expand All @@ -90,7 +93,7 @@ private Long processBid(CustomUserDetails customUserDetails, BidRequest bidReque

boolean isAuctionSuccessful = isAuctionSuccessful(userIdAndCurrentPrice, bidRequest);
BidLogging bidLogging = createBidLogging(user.getId(), productId, user.getGender(),
bidRequest.getBiddingPrice(), user.getAge(), isAuctionSuccessful);
bidRequest.getBiddingPrice(), user.getAge(), isAuctionSuccessful);
bidLoggingService.logging(bidLogging);

if (userIdAndCurrentPrice == null) { // 최초 입찰
Expand All @@ -117,7 +120,7 @@ private void isBiddingAvailable(CustomUserDetails user, BidRequest bidRequest, L
}

private Long updateRedisBidData(CustomUserDetails user, RMap<Long, Pair<Long, Long>> bidMap, BidRequest bidRequest,
Long productId) {
Long productId) {
Pair<Long, Long> newPair = Pair.of(user.getUser().getId(), Long.valueOf(bidRequest.getBiddingPrice()));
bidMap.put(productId, newPair); // productId에 대한 최고가 정보 업데이트
return Long.valueOf(bidRequest.getBiddingPrice());
Expand All @@ -136,7 +139,7 @@ private double increaseRate(Long previousPrice, int nextPrice) {
}

private BidLogging createBidLogging(Long userId, Long productId, Gender gender, int age, int price,
boolean isAuctionSuccessful) {
boolean isAuctionSuccessful) {
ProductFindResponse product = productFacade.findById(productId);
return BidLogging.builder()
.userId(userId)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package com.example.moduleapi.service.auction;

import com.example.moduleapi.controller.response.product.ProductFindResponse;
import com.example.moduleapi.service.product.ProductFacade;
import com.example.moduledomain.domain.user.CustomUserDetails;
import com.example.moduledomain.domain.user.User;
import com.example.moduledomain.repository.auction.EmitterRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Map;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import com.example.moduleapi.service.product.ProductFacade;
import com.example.moduledomain.domain.user.CustomUserDetails;
import com.example.moduledomain.domain.user.User;
import com.example.moduledomain.repository.auction.EmitterRepository;
import com.example.moduledomain.response.ProductFindResponse;

@Service
public class HighestBidSseNotificationService {
private final EmitterRepository emitterRepository;
Expand All @@ -34,7 +35,7 @@ public SseEmitter subscribe(CustomUserDetails user, Long productId) {
// 503 에러 방지를 위한 데이터 전송
// Emitter를 생성하고 나서 만료 시간까지 아무런 데이터도 보내지 않으면 재연결 요청시 503 Service Unavailable 에러가 발생할 수 있음.
send(emitter, user.getUser(), productId, "SSE Emitter Created. [userId=" + user.getUser().getUserId() + "]",
"SSE CONNECT.");
"SSE CONNECT.");
return emitter;
}

Expand All @@ -59,10 +60,10 @@ public void sendToAllUsers(Long productId, Object data, String comment) {
private void send(SseEmitter sseEmitter, User user, Long productId, Object data, String comment) {
try {
sseEmitter.send(SseEmitter.event() // SSE 이벤트를 생성하고 해당 Emitter로 전송합.
.id(productId.toString()) // 이벤트의 고유 ID (문자열 형태로 변환)
.name("THE HIGHEST PRICE UPDATE") // 이벤트의 이름을 "THE HIGHEST PRICE UPDATE"로 지정
.data(data) // 전송할 데이터
.comment(comment)); // 이벤트에 대한 코멘트
.id(productId.toString()) // 이벤트의 고유 ID (문자열 형태로 변환)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indent가 왜이렇게 차이가 많이나죠

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

엇 뭔가 이상해졌군요... 수정하겠습니다..

.name("THE HIGHEST PRICE UPDATE") // 이벤트의 이름을 "THE HIGHEST PRICE UPDATE"로 지정
.data(data) // 전송할 데이터
.comment(comment)); // 이벤트에 대한 코멘트
} catch (IOException e) {
emitterRepository.deleteEmitter(user, productId);
sseEmitter.completeWithError(e);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.example.moduleapi.service.file;

import com.example.moduleapi.controller.response.ImageResponse;
import java.util.List;

import org.springframework.web.multipart.MultipartFile;

import com.example.moduledomain.domain.product.Product;
import com.example.moduledomain.domain.product.ProductImage;
import com.example.moduledomain.domain.user.User;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import com.example.moduledomain.response.ImageResponse;

public interface FileService {
List<ProductImage> uploadImages(User user, Product product, List<MultipartFile> images);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
package com.example.moduleapi.service.file;

import com.example.moduleapi.controller.response.ImageResponse;
import com.example.moduleapi.exception.file.CreateDirectoryFailException;
import com.example.moduleapi.exception.file.DeleteImageFailException;
import com.example.moduleapi.exception.file.ImageFileUploadFailException;
import com.example.moduledomain.domain.product.Product;
import com.example.moduledomain.domain.product.ProductImage;
import com.example.moduledomain.domain.user.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
Expand All @@ -23,6 +10,20 @@
import java.util.UUID;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import com.example.moduleapi.exception.file.CreateDirectoryFailException;
import com.example.moduleapi.exception.file.DeleteImageFailException;
import com.example.moduleapi.exception.file.ImageFileUploadFailException;
import com.example.moduledomain.domain.product.Product;
import com.example.moduledomain.domain.product.ProductImage;
import com.example.moduledomain.domain.user.User;
import com.example.moduledomain.response.ImageResponse;

@Service
@Profile("dev")
public class LocalFileService implements FileService {
Expand Down Expand Up @@ -51,8 +52,8 @@ public List<ProductImage> uploadImages(User user, Product product, List<Multipar
@Override
public List<ImageResponse> loadImages(List<ProductImage> productImages) {
return productImages.stream()
.map(ImageResponse::from)
.collect(Collectors.toList());
.map(ImageResponse::from)
.collect(Collectors.toList());
}

@Override
Expand Down Expand Up @@ -98,19 +99,19 @@ private String createNewImageFileName(String originalImageFile) {
String uuid = UUID.randomUUID().toString();
String extension = StringUtils.getFilenameExtension(originalImageFile);
StringBuilder newName = new StringBuilder()
.append(uuid)
.append(".")
.append(extension);
.append(uuid)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 또 들어왔네요 ㅋㅋ 신기하네

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

엇 뭔가 저장하면서 수정된거같군용...

.append(".")
.append(extension);
return String.valueOf(newName);
}

private String createSavedImageFullPath(String userId, String savedImageFileName) {
StringBuilder fullDirectoryPath = new StringBuilder()
.append(baseUrl)
.append(File.separator)
.append(userId)
.append(File.separator)
.append(savedImageFileName);
.append(baseUrl)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반복문 돌면서 만들어내는게 아니면 String.format 써도 좋을 것 같아요 ~

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앗 넵 확인하고 수정하도록 하겠습니다!

.append(File.separator)
.append(userId)
.append(File.separator)
.append(savedImageFileName);
return String.valueOf(fullDirectoryPath);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,27 @@
import java.util.List;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;

import com.example.moduleapi.controller.response.product.ProductFindResponse;
import com.example.moduleapi.service.httpClient.circuitBreaker.RecommendationFallBackMethod;
import com.example.moduledomain.domain.product.Category;
import com.example.moduledomain.domain.product.ProductCondition;
import com.example.moduledomain.domain.user.Gender;
import com.example.moduledomain.request.ProductFilter;
import com.example.moduledomain.response.ProductFindResponse;

import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;

@FeignClient(name = "productRecommendationClient", url = "http://127.0.0.1:8085/api/v1/products", fallback = RecommendationFallBackMethod.class)
@CircuitBreaker(name = "recommendationServer")
public interface ProductRecommendationServerClient {

@GetMapping("/recommendations")
@PostMapping("/_recommendations")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 언더바가 있네요 ?

Copy link
Collaborator Author

@JIWON27 JIWON27 Jan 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추천 상품 조회 서버에도 POST 조회로 수정하면서 언더바 붙였는데 .. _가 의미가 없다면 수정하도록 하겠습니다!

List<ProductFindResponse> getRecommendationProduct(
@RequestHeader("Authorization") String authorizationHeader,
@RequestParam("gender") Gender gender,
@RequestParam("age") int age,
@RequestParam String keyword,
@RequestParam List<Category> categories,
@RequestParam List<ProductCondition> productConditions
@RequestBody ProductFilter productFilter
);
}
Loading
Loading