CQRS (Command Query Responsibility Segregation)
단일 모델의 장점 #
ORM 기법은 조회 기능에 적합하지 않아 상태 변경 모델과 조회 모델을 분리해야한다.
보통 조회 기능을 구현할 때 여러 애그리거트의 데이터가 필요한 경우가 많다.
하지만 조회 화면 특성상 조회 속도가 빠를수록 좋기 때문에 구현 방법을 고민해야한다.
식별자를 이용해 애그리거트를 참조하는 방식을 사용하면 즉시 로딩 방식과 같은 JPA의 쿼리 관련 최적화 기능을 사용할 수 없다.
직접 참조하는 방식으로 연결해도 조회 화면 특성에 따라 같은 연관도 즉시 로딩이나 지연 로딩으로 처리해야 하기 때문이다.
이런 문제가 발생하는 이유는 시스템 상태를 변경할 때와 조회할 때 단일 도메인 모델을 사용하기 때문이다.
ORM 기법은 도메인 상태 변경 기능을 구현하는 데는 적합하지만 여러 애그리거트에서 데이터를 가져와 출력하는 기능을 구현하기에는 고려할 게 많아 구현을 복잡하게 만드는 원인이 된다.
구현 복잡도를 낮추기 위한 상태 변경 모델과 조회 모델을 분리하는 것이다.
CQRS #
시스템이 제공하는 기능은 크게 상태를 변경하는 기능과, 상태 정보를 조회하는 기능으로 나눌 수 있다.
도메인 모델 관점에서 상태 변경 기능은 주로 한 애그리거트의 상태를 변경한다.
반면 조회 기능에 필요한 데이터를 표시하려면 두 개 이상의 애그리거트가 필요할 때가 많다.
두 기능의 범위가 정확하게 일치하지 않기 때문에 단일 모델로 두 종류의 기능을 구현하면 모델이 복잡해진다.
단일 모델을 사용할 때 발생하는 복잡도를 해결하기 위해 사용하는 방법이 CQRS다.
CQRS는 Command Query Responsibility Segregation의 약자로 상태를 변경하는 명령을 위한 모델과 상태를 제공하는 조회를 위한 모델을 분리하는 패턴이다.

도메인이 복잡할수록 명령 기능과 조회 기능이 다루는 데이터 범위에 차이가 나 CQRS가 적합하다.
CQRS를 사용하면 다음과 같이 각 모델에 맞는 구현 기술을 선택할 수 있다.

상태 변경을 위한 명령 모델은 객체를 기반으로 한 도메인 모델을 이용해 구현한다.
조회 모델은 조회 기능에 필요한 정보를 담고 있는 데이터 타입을 이용한다.
명령 모델은 상태를 변경하는 도메인 로직을 수행하는 데 초첨을 맞춰 설계했고, 조회 모델은 화면에 보여줄 데이터를 조회하는 데 초점을 맞춰 설계했다.

명령 모델과 조회 모델이 서로 다른 데이터 저장소를 사용할 수도 있다.
명령 모델은 트랜잭션을 지원하는 RDBMS를 사용하고, 조회 모델은 조회 성능이 좋은 메모리 기반 NoSQL을 사용할 수 있다.

웹과 CQRS #
일반적인 웹 서비스는 상태를 변경하는 요청보다 상태를 조회하는 요청이 많다.
따라서 개발팀의 조회 성능을 높이기 위해 기본적으로 쿼리를 최적화하고 메모리 조회 데이터를 캐싱 해서 응답 속도를 높이기도 한다.
혹은 조회 전용 저장소를 따로 사용하기도 한다.
이런 다양한 기법들을 결과적으로 CQRS를 적용하는 것과 같은 효과를 만든다.
CQRS 장단점 #
명령 모델을 구현할 때 도메인 자체에 집중할 수 있다는 장점이 있다.
명령 모델에서 조회 관련 로직이 사라져 복잡도가 낮아지고 도메인 로직을 구현하는 데 집중할 수 있다.
또 조회 단위로 캐시 기술을 적용할 수 있고 조회에 특화된 쿼리를 마음대로 사용할 수 있어 조회 성능을 향상시크는 데 유리하다.
조회 저장소를 사용하면 조회 처리량을 대폭 늘릴 수 있다.

하지만 구현해야 할 코드가 더 많고 더 많은 구현 기술이 필요하다는 단점이 있다.
장단점을 고려해 CQRS 패턴을 도입할지 여부를 결정해야 한다.