B2C 플랫폼 설계/설계

💻 [B2C 플랫폼 설계] 18편 - 장바구니 서비스 구현하기

프로그래민구찌 2025. 5. 31. 18:43

🎯 개요

이번 글에서는 cart-service를 새롭게 분리하여, Redis 기반으로 장바구니 기능을 구현한 과정을 정리하였습니다.
회원이 상품을 장바구니에 추가하고, 조회 및 삭제하는 흐름을 실시간 Redis에 저장하며 구성하였습니다.

장바구니는 상품처럼 영구 저장이 아닌, 일정 기간 보관 후 만료되는 구조가 자연스럽기에 Redis TTL 기반으로 설계하였습니다.


✅ 주요 기능 요약

기능 설명
장바구니 추가 상품 ID와 수량을 전달받아 Redis에 장바구니 항목 저장
장바구니 조회 로그인된 사용자 기준으로 장바구니 항목 전체 조회
장바구니 삭제 특정 상품 ID에 대한 장바구니 항목 제거
TTL 설정 Redis에 저장된 장바구니는 7일간 유효하며 이후 자동 만료
상품 유효성 검사 FeignClient로 product-service의 상품 존재 여부 확인
예외 응답 포맷 통일 공통 ApiResponse 구조로 404, 400 에러 메시지 반환

🛠️ 기술 스택

  • Spring Boot 3.x
  • Spring Web, Lombok
  • Spring Data Redis
  • RedisTemplate + TTL 설정
  • FeignClient (상품 정보 연동)
  • Spring Security (AuthenticationPrincipal)
  • Common-library (공통 예외 및 응답 구조)

🔧 예제 흐름 설명

1. 장바구니에 상품 추가

  • URL: POST /cart
  • 헤더: Authorization: Bearer {AccessToken}
  • 요청 바디:
{
  "productId": 1,
  "quantity": 3
}
 
  • 응답 예시:
{
  "success": true,
  "data": null,
  "message": null
}
  • 예외 응답 (상품 없음):
{
  "success": false,
  "data": null,
  "message": "해당 상품을 찾을 수 없습니다. ID=500"
}

2. 장바구니 목록 조회

  • URL: GET /cart
  • 헤더: Authorization: Bearer {AccessToken}
  • 응답 예시:
{
  "success": true,
  "data": {
    "1": {
      "productId": 1,
      "quantity": 3
    },
    "2": {
      "productId": 2,
      "quantity": 1
    }
  },
  "message": null
}

3. 장바구니 항목 삭제

  • URL: DELETE /cart/{productId}
  • 헤더: Authorization: Bearer {AccessToken}
  • 응답 예시:
{
  "success": true,
  "data": null,
  "message": null
}

🧠 회고 및 팁

  • 장바구니는 보통 짧은 기간의 상태성 데이터이기 때문에, RDB보다 Redis가 더 적합하다고 판단했습니다.
  • TTL 설정을 통해 비활성 사용자 장바구니를 자동 정리할 수 있어 리소스 관리에도 유리합니다.
  • 상품 유효성 검사를 product-service로 위임하여 도메인 간 책임 분리를 유지할 수 있었습니다.
  • FeignClient 사용 시 발생하는 예외를 핸들링하기 위해 LocalExceptionHandler에서 FeignException을 포괄 처리하였고, 공통 ApiResponse 포맷으로 정리하여 응답 일관성을 유지했습니다.

📚 추가 자료