CQRS(Command Query Responsibility Segregation)은 명령(Command)과 조회(Query)를 분리하여 시스템 설계를 단순화하고 성능과 확장성을 높이는 아키텍처 패턴이다.
“쓰기와 읽기의 책임 분리”라는 개념을 중심으로, 두 가지 작업의 요구사항을 독립적으로 처리한다.
다음과 같은 문제를 해결하기 위해 CQRS가 도입된다:
전자상거래 시스템에서 다음과 같은 작업이 수행된다고 가정하자:
쓰기와 읽기를 분리하면 각 작업의 요구사항에 최적화된 데이터 모델을 사용하여 성능과 확장성을 개선할 수 있다.
[Command Input] ---> [Command Model] ---> [Write Database]
\ ^
\ /
\ /
--> [Query Model] --> [Read Database]
|
[Query Input]
주문 생성 서비스:
// 도메인 모델: Order
public class Order {
private String id;
private String product;
private int quantity;
// 생성자 및 getter/setter
public Order(String id, String product, int quantity) {
this.id = id;
this.product = product;
this.quantity = quantity;
}
}
// 명령 처리 서비스
public class OrderCommandService {
private final OrderRepository repository;
public OrderCommandService(OrderRepository repository) {
this.repository = repository;
}
public void createOrder(Order order) {
repository.save(order);
}
}
주문 조회 서비스:
// 조회 DTO
public class OrderDTO {
private String id;
private String product;
private int quantity;
public OrderDTO(String id, String product, int quantity) {
this.id = id;
this.product = product;
this.quantity = quantity;
}
// getter만 제공
}
// 조회 처리 서비스
public class OrderQueryService {
private final OrderReadRepository repository;
public OrderQueryService(OrderReadRepository repository) {
this.repository = repository;
}
public List<OrderDTO> getOrders() {
return repository.findAll();
}
}
// 쓰기 전용 저장소
public interface OrderRepository {
void save(Order order);
}
// 읽기 전용 저장소
public interface OrderReadRepository {
List<OrderDTO> findAll();
}
OrderCommandService
를 호출하여 주문을 생성.OrderRepository
가 쓰기 데이터베이스를 갱신.OrderQueryService
를 호출하여 주문 목록을 조회.CQRS는 성능과 확장성 향상이 필요한 시스템에서 특히 유용하다.
다른 아키텍처 패턴이 궁금하다면 아래 글도 확인해보세요.
아래 글에서 다른 아키텍쳐 패턴들을 확인할 수 있다.
아키텍처 패턴 모음