728x90
API를 만들기 위해 총 3개의 클래스 필요
- Request 데이터를 받을 Dto
- API 요청을 받을 Controller
- 트랜잭션, 도메인 기능 간 순서를 보장하는 Service
Service에서 비지니스 로직을 처리한다?
(X)
Web Layer
- 컨트롤러(@Controller)와 JSP/Freemarker 등 뷰 템플릿 영역
- 필터(@Filter), 인터셉터, 컨트롤러 어드바이스 등
외부 요청과 응답
에 대한 전반적 영역
Service Layer
- @Service에 사용되는 서비스 영역
- 일반적으로 Controller와 Dao의 중간 영역에서 사용됨.
- @Transactional이 사용되어야 하는 영역
Repository Layer
- Database와 같이 데이터 저장소에 접근하는 영역 (Dao 영역과 유사)
Dtos
- Dto는
계층 간에 데이터 교환을 위한 객체
. Dtos는 이들의 영역. - 뷰 템플릿 엔진에서 사용될 객체나 Repository Layer에서 결과로 넘겨준 객체 등
- Dto는
Domain Model
- 도메인(택시앱일 때 배차, 탑승, 요금 등)이라 불리는 개발대상을 모든 사람이 동일한 관점에서 이해할 수 있고 공유할 수 있도록 단순화 시킨 것
- @Entity역시 도메인 모델
- 테이블과 관계가 있는 것들 뿐 아니라 VO처럼 각 객체들도 해당
이 중 비지니스 처리를 담당하는 곳은 Domain
Domain에서 비지니스 처리하기
- 다음과 같은 주문 취소 로직이 있다고 하자.
@Transactional
public Order cancelOrder(int orderId){
1) 데이터베이스로부터 주문정보 ( Orders ), 결제 정보 (Billing), 배송정보 (Delivery) 조회
2) 배송취소를 해야 하는지 확인
3) (if 배송중이라면){
배송 취소 변경
}
1) 각 테이블에 취소 상태 Update
}
- 기존에 서비스로 처리하던 방식 (트랜잭션 스크립트)
: 모든 로직이 서비스 클래스 내부에서 처리 됨. (상태 set하는 것)
그러다 보니 서비스가 무의미하고, 객체란 단순히 데이터 덩어리 역할만함.
@Transactional
public Order cancelOrder(int orderId){
// 1) 데이터베이스로부터 주문정보 ( Orders ), 결제 정보 (Billing), 배송정보 (Delivery) 조회
OrdersDto order = ordersDao.selectOrders(orderId);
BillingDto billing = billingDao.selectBilling(orderId);
DeliveryDto delivery = deliveryDao.selectDelivery(orderId);
// 2) 배송취소를 해야 하는지 확인
String deliveryStatus = delivery.getStatus();
/*3) (if 배송중이라면){
배송 취소 변경
}*/
if("IN_PROGRESS".equals(deliveryStatus)){
delivery.setStatus("CANCEL");
deliveryDao.update(delivery);
}
// 4) 각 테이블에 취소 상태 Update
order.setStatus("CANCEL");
ordersDao.update(order);
billing.setStatus("CANCEL");
deliveryDao.update(billing);
return order;
}
- 도메인 모델
order, billing, delivery가 각자 본인의 취소 이벤트 처리를 하며, 서비스 메소드는트랜잭션과 도메인 간의 순서만 보장
해 줌.
@Transactional
public Order cancelOrder(int orderId){
// 1) 데이터베이스로부터 주문정보 ( Orders ), 결제 정보 (Billing), 배송정보 (Delivery) 조회
Orders order = ordersRepository.findById(orderId);
Billing billing = billingRepository.findByOrderId(orderId);
Delivery delivery = deliveryRepository.findByOrderId(orderId);
/*2) 배송취소를 해야 하는지 확인
3) (if 배송중이라면){
배송 취소 변경
}*/
delivery.cancel();
// 4) 각 테이블에 취소 상태 Update
order.cancel();
billing.cancel();
return order;
}
'Web > 📗 Spring' 카테고리의 다른 글
Entity와 DTO [Spring / 스프링 부트와 AWS로 혼자 구현하는 웹 서비스] (0) | 2022.07.18 |
---|---|
[Spring] 스프링에서 Scheduler 사용하기 (0) | 2022.07.18 |
롬복 소개 및 설치하기 [Spring / 스프링 부트와 AWS로 혼자 구현하는 웹 서비스] (0) | 2022.07.08 |
테스트 코드 작성하기 [Spring / 스프링 부트와 AWS로 혼자 구현하는 웹 서비스] (0) | 2022.07.08 |
테스트 코드 소개 (TDD) [Spring / 스프링 부트와 AWS로 혼자 구현하는 웹 서비스] (0) | 2022.07.07 |
댓글