Command and Query Responsibility Segregation
명령과 쿼리의 권한 분리.
DB나 상태를 변화(mutate)시키는 '명령(command)'과, 조회만 하는 '쿼리(query)'를 분리하자는 이야기.
변화시키는 요청은, Queue 같은 곳에 command를 발행하고, worker가 받아서 command를 실행하면서 수정을 처리.
조회하는 요청은 DB에서 직접 끌어와서 처리.
장점은?
우선, Event Source pattern을 위해서는 CQRS가 필수적이라는 의견.
Microsoft의 CQRS 문서 참고. Popit에 게제된 글도 읽어볼만하다. RDBMS와 NoSQL을 hybrid로 사용해서, command는 RDB에 대해서, read는 NoSQL에서 한다는 발상이 독특했다. RDBMS to NoSQL sync는 어떻게 유지하지? 하긴, NoSQL이 아니라 cache라고 이해해도 괜찮은 것 같다.
애초에 CQRS가 궁금했던게, SQS + Lambda를 기반으로 하는, event sourcing pattern으로 시스템을 구성할 수는 없을까 했었다.
Web API에서는 그냥 간단하게 SQS에 command message만 발행하고, 뒷단에서 lambda가 받아서 수정을 처리하는.
command는 event sourceing pattern으로 한다 하더라도, query는 예전처럼 동기 방식으로 구현해야 할듯.
이슈/문제는?
이를테면 DeepNatural AI 플랫폼에서 task assign하는 로직 같은 경우, 곧바로 assign에 대한 처리 결과가 필요한데, 이것은 어떻게 하나? 요청에 uuid를 발급하고, 그 uuid로 처리 결과를 조회하도록? 그 때까지는 대기? 프론트엔드면 몰라도, 서비스간에 의존 관계가 있는 경우엔, 서버가 대기할 수는 없으니. async를 적용해야 하나?
- command들 간에 연관이 필요한 경우? 한 command가 너무 복잡한 경우, sub command들의 composition으로 구성해야 하나?
ActiveRecord 방식 ORM의 장점을 포기하게 될 수 있다. RepositoryPattern 을 사용해야 한다는 얘기들이 많다. (OrmAndRepository)
좌충우돌 ORM 개발기 Python으로 클린 아키텍처 적용하기, Django API Domains
ORM은 그냥 두고 Service에서 처리하는 것도 좋다는 의견도 있다. QueryService, CommandService.
ActiveRecord 방식의 ORM의 특징? 장점?
- JOIN 등, 연관 레코드 조회가 편하다.
JOIN을 분리할 수 있다면, DB가 꼭 RDBMS일 필요는 없다. NoSQL이어도 되고, command 방식으로 한다면 Redis도 괜찮다.