프로젝트

(ProfitKey) 컨트롤러 경로 변수 userId 인코딩 문제 해결

민톨이 2025. 3. 3. 19:27
728x90

- 종목 찜하기 Service단

@Transactional
	public void addFavoriteStock(Long userId, String stockCode) {
		UserInfo user = userInfoRepository.findById(userId)
			.orElseThrow(() -> new IllegalArgumentException("User not found for ID: " + userId));

		StockCode stockCodeEntity = stockCodeRepository.findByStockCode(stockCode);
		if (stockCodeEntity == null) {
			throw new IllegalArgumentException("Stock code not found for: " + stockCode);
		}

		FavoriteStock favoriteStock = FavoriteStock.builder()
			.user(user)
			.stockCode(stockCodeEntity)
			.build();

		favoriteStockRepository.save(favoriteStock);
	}

 

- 종목 찜하기 Controller단

	@PostMapping("{userId}/favorite-stocks")
	@Operation(summary = SwaggerDocs.SUMMARY_POST_FAVORITE_STOCKS, description = SwaggerDocs.DESCRIPTION_POST_FAVORITE_STOCKS)
	public void addFavoriteStock(@RequestBody FavoriteStockRequest request) {
		myPageService.addFavoriteStock(request.getUserId(), request.getStockCode());
	}

 

이렇게 해둔 상태인데, 

 

스웨거에서 테스트를 해보았을 때에 프론트에서 요청값이 이상하다는 지적이 들어왔다

 

userId가 string으로 받아져서 { }가 인코딩된 채로 뜨는 ;;

 

 

문제의 부분이다.

 

요청값이 저렇게 뜨는 것에 대한 이유는 ?

 

=> 경로 변수인 {userId}를 제대로 처리하지 않고 문자열로 그대로 전달하기 때문이다

 

request body에서 userId를 받을 필요가 없을 것 같다는 결론을 내고 코드를 수정했다.

 

Request단

@Getter
@Setter
@NoArgsConstructor
@Schema(description = "관심 종목 추가 요청")
public class FavoriteStockRequest {

	// @Schema(description = "사용자 ID", example = "1")
	// private Long userId;  =====>> 삭제

	@Schema(description = "주식 코드", example = "005930")
	private String stockCode;
}

 

Request에서 userId를 주석 처리해주었다.

 

	@GetMapping("/favorite-stocks/{userId}")
	@Operation(summary = SwaggerDocs.SUMMARY_FAVORITE_STOCKS, description = SwaggerDocs.DESCRIPTION_FAVORITE_STOCKS)
	public ResponseEntity<List<FavoriteStockResponse>> getFavoriteStocks(@PathVariable Long userId) {
		List<FavoriteStockResponse> response = myPageService.getFavoriteStocks(userId);
		return ResponseEntity.ok(response);
	}

 

이렇게 하면 userId는 URL에서 @PathVariable로 추출되고, 요청 본문에서는 stockCode만 받게 된다.

이 방식의 장점 ?

  • 중복 제거: userId를 URL에서 받아오는 것만으로 충분하기 때문에 요청 본문에서 userId를 중복해서 받을 필요가 없음
  • API의 일관성 유지: userId는 경로 변수로, 주식 코드(stockCode)는 요청 본문으로 받는 방식이 직관적입니다. 경로 변수는 리소스를 식별하는데 사용하고, 본문은 리소스에 대한 데이터를 담는 방식임

결론적으로, requestBody에서 userId를 지우고, 경로 변수로만 userId를 받으면 된다.

 

이렇게 코드를 수정했더니

 

이렇게 {} 인코딩과 userId를 String으로 받아오는 것이 아니라 6으로 잘 받아오게 된다.