1. API 만들기

API를 구현하려면 총 3개의 클래스가 필요하다.

보통 Service는 비즈니스 로직을 처리한다고 오해하는데, 사실 트랜잭션, 도메인 간의 순서를 보장하는 역할만 한다.

1-1. 비즈니스 로직은 누가 처리할까?

1-2. 트랜잭션 스크립트 / 도메인 모델

  1. 트랜잭션 스크립트

    public class Example {
        @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);
            biling.setStatus("CANCEL");
            deliveryDao.update(biling);
    
            return order;
        }
    }
    

    서비스에서 처리하는 방식을 트랜잭션 스크립트라고 한다. 모든 로직이 서비스 클래스 내부에서 처리되다보니 서비스 계층이 무의미하고, 객체가 단순히 데이터 덩어리 역할만 하게 된다.

  2. 도메인 모델

    public class Example {
        @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();
        }
    }
    

    order, billing, delivery가 각자 본인의 취소 이벤트를 처리한다. 서비스 메서드는 트랜잭션과 도메인 간의 순서만 보장한다.

    이 프로젝트에서는 도메인 모델을 다룰 것이다.

Reference