웹 어댑터는 외부로부터 요청을 받아 애플리케이션 코어를 호출한다.
제어 흐름은 웹 어댑터에 있는 컨트롤러에서 애플리케이션 계층에 있는 서비스로 흐른다.
애플리케이션 계층은 웹 어댑터가 통신할 수 있는 특정 포트를 제공한다.
서비스는 이 포트를 구현하고, 웹 어댑터는 포트를 호출한다.
제어 흐름을 봐서는 웹 어댑터가 유스케이스를 직접 호출해도 되는데, 왜 굳이..? 포트를..?
또한 상호작용이 많이 일어나는 애플리케이션에서! [웹 소켓]
위 그림처럼 애플리케이션이 웹 어댑터에 능동적으로 알림을 줘야한다면, 의존성을 올바른 방향으로 유지하기 위해 아웃고잉 포트를 통과해야한다! [웹 → 서비스로 바로 포트 없이 의존하고 있었다면 의존성이 순환하게 된다!]
이때 아웃고잉 포트를 구현하기 때문에, 웹 어댑터는 인커밍 어댑터인 동시에 아웃고잉 어댑터가 된다.
- HTTP 요청을 자바 객체로 매핑
- 권한 검사
- 입력 유효성 검증
- 입력을 유스케이스의 입력 모델로 매핑
- 유스케이스 호출
- 유스케이스의 출력을 HTTP로 매핑
- HTTP 응답을 반환
웹 어댑터 입력 모델은 유스케이스 입력 모델과 구조나 의미가 완전히 다를 수 있다! → 또 다른 유효성 검증을 수행해야 한다.
웹 어댑터의 책임이 매우 많아보인다. 하지만 이 책임들은 애플리케이션 계층이 신경 쓰면 안되는 것들이다!
HTTP와 관련된 것이 애플리케이션 계층으로 침투하면 안 된다.
웹 어댑터와 애플리케이션 계층 간의 이 같은 경계는 도메인과 애플리케이션 계층부터 개발하기 시작하면 자연스럽게 생긴다.
웹 어댑터 → 1개 이상의 클래스로 구성 가능!
컨트롤러는 얼마나 만들어야하는가?
클래스마다 코드는 적을수록 좋다!
컨트롤러에 코드가 많다면 그에 해당하는 테스트 코드도 많아지게 된다!
모든 연산을 단일 컨트롤러에 모아놓으면...
별도의 패키지 안에, 별도의 컨트롤러를 만들자! → 메서드와 클래스명을 유스케이스를 최대한 반영해서!
이렇게 별도 컨트롤러를 만들고, 그에 대한 전용 클래스들이 생기게 되면!
이렇게 나누는 스타일의 또 다른 장점 → 서로 다른 연산에 대한 동시 작업이 쉬워진다!
웹 어댑터를 구현할 때
애플리케이션 계층은 HTTP에 대한 상세 정보를 노출시키지 않도록 HTTP와 관련된 작업을 해서는 안 된다!
웹 컨트롤러를 나눌 때, 모델을 공유하지 않는 여러 작은 클래스들을 만드는 것을 두려워해서는 안 된다!
물론 Cost가 더 있지만, 유지보수 측면에서 큰 이득이 있다!