프로젝트를 시작하기에 앞서 만드려는 사이트의 요구사항을 나열하고 아키텍처를 잡아보려고 한다.
1. '악기(상품)'를 '판매'하는 사이트
2. '유저'는 '관리자', '판매자', '일반'이 존재
3. '유저'는 '판매' '상품'을 '구매'하기 위해 '검색' 함
4. '검색'은 상품, 지역, 가격, 상태 등 '검색조건'이 존재
5. '상품'을 누르면 상세페이지에서 '구매'가 가능
6. '결제'는 '카드결제' 또는 '직접결제' 존재
7. '배송' 정보를 선택할 수 있음. '매장'에서 '배송'이 가능하다면 선택할 수 있음
8. '판매자'는 '매장'과 '상품'을 등록 할 수 있음.
그리고 ''안에 있는 것을 도메인으로 볼 수 있는지에 대해 GPT한테 물어봤다.
도메인을 어떻게 나누느냐는 **업무 모델(비즈니스 로직)**과 **데이터(엔티티)**를 어떻게 그룹화하느냐에 달려 있습니다. 말씀하신 식으로 ‘판매’, ‘구매’, ‘검색’, ‘결제’, ‘배송’, ‘유저’, ‘매장’, ‘상품’ 등을 각각 도메인으로 볼 수도 있습니다. 다만 실제 구현 단계에서, 너무 세분화하면 오히려 복잡해질 수 있고, 너무 크게 뭉뚱그리면 한 도메인에 로직이 과도하게 모일 수 있죠.
아래는 일반적인 전자상거래(이커머스) 관점에서 참고할 만한 도메인 분할 예시입니다. 각 항목 옆에, 질문에서 언급하신 “‘~’ 안에 있는 걸로 볼 수 있을까?”를 연결해드렸습니다.
1. 유저(User) 도메인
• 관리자, 판매자, 일반 사용자(구매자) 등의 **역할(Role)**을 포함
• 로그인, 회원가입, 권한 관리, 프로필 관리 등
(→ “‘유저’는 ‘관리자’, ‘판매자’, ‘일반’” 이라고 하셨으니, 이 부분이 User 도메인에 해당)
2. 상품(Product / Listing) 도메인
• 악기(상품) 등록, 조회, 수정, 삭제 등 CRUD
• “‘상품’을 등록” → 판매자가 올리는 매물(“판매”)
(→ “악기(상품)를 판매하는 사이트” 라고 하셨으니, 실제로는 Product나 Listing 같은 도메인으로 볼 수 있습니다. “판매” 로직과 연결되지만, 실제 도메인 이름을 Product로 두고 “등록/수정/삭제” 기능을 제공하는 식입니다.)
3. 매장(Shop) 도메인
• 판매자 중 ‘매장(인증 업체)’ 개념이 있을 경우 별도 도메인으로 구분
• 매장 정보(상호, 주소, 전화번호, 영업시간, 등록 상품 목록 등) 관리
(→ “판매자”가 개인뿐 아니라 “매장”일 수도 있다고 하셨으므로, 이 부분은 Shop 도메인으로 나눌 수 있습니다.)
4. 검색(Search) 도메인
• 상품, 지역, 가격, 상태 등 검색 조건을 관리하고 필터링, 정렬, 페이지네이션 제공
• 사실상 Product(또는 Listing) 도메인의 하위 기능으로 묶는 경우가 많지만, 검색 기능이 매우 중요하거나 고도화(예: ElasticSearch)될 경우 별도 도메인(또는 마이크로서비스)로 분리 가능
(→ “검색은 상품, 지역, 가격, 상태 등 ‘검색조건’이 존재”)
5. 주문(Order) 도메인
• “상품을 누르면 상세페이지에서 구매가 가능” → 구매를 실행하면 주문(Order)이 생김
• 결제, 배송 로직은 일반적으로 주문과 결합해서 다루는 편이 많음
예를 들어, Order 엔티티가 있고 여기에 결제 상태(결제 완료, 결제 대기 등)와 배송 상태(배송 준비, 배송 중, 배송 완료)를 연결하여 트랜잭션적으로 관리하는 식입니다.
(→ “결제는 카드결제 혹은 직접결제”, “배송 정보를 선택 가능”, “매장 배송 여부” 등)
6. 결제(Payment) 도메인
• 카드결제, 직접결제(계좌이체 등) 수단별 결제 로직 처리
• 결제 내역, 취소/환불 로직, 영수증 발행 등
• 규모가 커지면 Order와 분리해서 Payment를 독립 도메인으로 관리
(→ “결제는 ‘카드결제’ 또는 ‘직접결제’ 존재”)
7. 배송(Shipping) 도메인
• 배송지 정보(수령인, 주소, 연락처), 운송장(택배사, 송장번호)
• 매장 or 개인이 배송을 제공하는지 여부
• 배송 상태 추적(“준비 중”, “배송 중”, “배송 완료”)
(→ “배송 정보를 선택할 수 있음. 매장에서 배송이 가능하면 선택 가능”)
8. (선택) 관리(Administration) 도메인
• 관리자만 접근 가능한 기능: 사용자 관리, 상품 승인/차단, 통계(매출, 거래량) 등
• 일반적으로 User 도메인에 ‘Admin’ 권한이 있으면, 별도로 구분하기보다는 “Admin 전용 API”로만 구분하기도 함
실제 프로젝트에서의 정리 방식
1. User (역할: 관리자, 판매자, 일반)
2. Shop (매장 등록, 매장 정보 관리)
3. Product / Listing (상품 등록, 조회, 수정, 삭제, 검색필터)
4. Order (구매/주문 생성, 결제, 배송)
• 안에 Payment(결제) + Shipping(배송) 로직을 묶어서 관리
5. (옵션) Search(만약 검색을 대규모로 별도 처리 필요 시)
6. (옵션) Admin(관리자 대시보드, 통계, 권한 등)
일반적으로는 Order라는 큰 도메인에 “구매(Checkout) → 결제(Payment) → 배송(Shipping)” 절차가 한데 묶입니다. “판매”는 “누가 상품을 등록했는가?”라는 관점으로 Product(혹은 Listing)에 판매자 정보가 들어있다고 보기도 합니다.
정답 한눈에 요약
“필요한 기능을 나열해봤는데, 도메인을 ‘~’ 안에 있는 걸로 볼 때 이렇게 볼 수 있을까?”
네, 크게는 아래처럼 도메인을 잡으면 자연스러울 것입니다:
1. 유저(User): (관리자, 판매자, 일반 사용자)
2. 매장(Shop): (판매자 중 ‘매장’ 개념)
3. 상품(Product/Listing): (등록, 수정, 검색, 조회, 판매)
4. 주문(Order): (구매, 결제, 배송)
• Payment(카드/직접결제)
• Shipping(배송 여부)
5. (선택) 검색(Search) 도메인을 독립(혹은 Listing에 포함)
6. (선택) 관리자(Admin) 전용 도메인(또는 User의 권한 구분으로 처리)
위처럼 정리하면, 말씀하신 시나리오(악기 중고/새 제품 판매 + 결제 + 배송 + 검색 + 역할 분리)에 잘 부합하는 구조가 됩니다.
최대한 행동을 세분화 해서 나누었는데 시나리오 기준으로 적절한 도메인을 잘 뽑아주었다.
이를 바탕으로 백엔드 서버의 아키텍처를 잡아보았다.
- adapter영역은 바깥과 이어지는 영역이다. db와 연결되는 persistence와 controller가 있는 web으로 분류하였다. entity는 persistence에 있다.
- application 영역은 port에서 in/out interface를 정의해준다. 이를 바탕으로 adapter영역과 연결해주었다.
- application 영역의 service는 사실상 usecase가 될 것 같다.
- domain을 위를 바탕으로 나누었다. 그리고 DomainService를 만들었다. 기존에 Domain이 복잡한 기능을 가지게 되었을 때에 대한 고민을 했었는데 Domain Service를 Domain 영역에 넣어서 다루는 방법이 있다!
아키텍처는 앞으로 계속 수정될 것이다. 더 좋은 방법을 찾아서 :)
'PROJECT' 카테고리의 다른 글
week2-1: Spring Security 비활성화 및 Swagger 적용, User 테이블 만들기 (0) | 2025.02.24 |
---|---|
Week 1: 사이드프로젝트를 시작해보자 with AI (0) | 2025.02.21 |
[SpringBoot] WebSecurityConfigurerAdapter 지원 불가 (6) | 2022.04.05 |
[SpringBoot] Spring Boot 3.0.0 버전 설정 (0) | 2022.02.20 |
[Vue.js] 백엔드/프론트엔드 연결하기 with axios (0) | 2022.02.02 |