Controller -> Service 처리 과정에서 DTO 패턴을 적용하여 Request, Response객체를 넘기지 않고 한번 변환하는 경우를 종종 보는데, 아래 2가지 방식에 따라 때론 DTO가 필요 없으며, 그냥 req, res를 주고받는게 괜찮다고 생각한다
오케스트레이션의 주체에 따라 2가지 패턴이 있는데
1. Controller가 Service를 오케이스트레이션 하는지?
2. Service가 Domain 모델 (repository, entity, domain service)을 오케이스트레이션 하는지?
하나의 도메인으로 요청을 모두 해결할수 있는 서비스는 잘 없다.
누군가 오케스트레이터가 되어야 하는데, 나는 많은 경우 2번 패턴을 택했을거라 생각 한다.
이유는, 컨트롤러가 오케스트레이션을 하기에는 트랜잭션도 없고, 도메인모델간의 의존성을 고려한 호출 순서 등을 고려하기엔 어울리지 않는다.
1번은 어플리케이션을 보호한다기 보다 서비스를 보호하는것에 가깝다고 생각한다.
난 서비스를 보호하는것도 매우 존중한다.
하지만 오케스트레이션을 하는것은 어플리케이션 서비스가 전담하고, 로직을 보호하고 싶다면 도메인서비스라는 계층을 추가로 둬서 위임하는 방법도 있다.
다시 돌아와서 2번 방식으로 좁혀서 얘길 좀 해보고 싶은데,
이경우 서비스는 Domain 모델들의 파사드
이자, 컨트롤러의 델리게이터
역할이 전부로, 도메인로직은 없고 오케스트레이션만 할수 있다.
이러면 대체로 컨트롤러 메소드와 서비스의 메소드가 1:1이 된다.
이러면 req, res를 주고받아도 어색하지 않고, 또한 Service -> Service 의존 할 일이 없다.
어플리케이션 서비스는 모듈마다 존재하며, 도메인서비스는 코어로 존재한다.
그래서 어플리케이션 서비스는 클라이언트 컨텍스트를 담을수 있다.
Actor는 중요한 요소이다.
Actor에 따라 어떤 도메인 커맨드를 쓸지, 권한이 있을지 충분히 다를수 있다.
req를 받을수 있고, 번역이 충분히 가능하기 때문에 DTO 를 주고받을 필요가 없다.
하지만 1번은 DTO가 필요하다.
왜냐하면, 여러개의 서비스가 있을때, 서비스들은 각자 이유가 있어서 경계를 두었고, 받고자 하는 파라미터도 한정되어 있다.
그래서 각각의 command, criteria, dto 등으로 쪼개서 호출해줘야 한다.