2023. 5. 12. 15:47ㆍDDD/CleanArchitecture
소개
만들면서 배우는 클린 아키텍처 책을 읽고 정리하며 소감을 적는 포스트입니다.
웹 어댑터 구현하기
UI나 다른 시스템에서 애플리케이션을 호출하는 방식으로 상호작용하는 HTTP API가 웹 어댑터에 해당 됩니다.
의존성 역전
아래의 그림은 웹 어댑터와 관련된 아키텍처 요소(어댑터 자체와 애플리케이션 코어와 상호작용 하는 포트)에 조금 더 초점을 맞춘 그림이다.
인커밍 어댑터는 애플리케이션 서비스에 의해 구현된 인터페이스인 전용 포트를 통해 애플리케이션 계층과 통신한다.
adapter.in.web
은 주도하는
어댑터이다. 제어 흐름은 웹 어댑터에 있는 컨트롤러에서 애플리케이션 계층에 있는 서비스로 흐른다.
애플리케이션 계층은 웹 어댑터가 통신할 수 있는 특정 포트를 제공한다.
위 그림은 의존성 역전 원칙
이 적용되어 있는데 왜 아래와 같이 직접 호출 하지 않는 것일까??
포트 인터페이스를 삭제하고 서비스를 직접 호출할 수 있다.
애플리케이션 코어가 외부 세계와 통신 할 수 있는 곳에 대한 명세가 있는 포트이기 때문이다. 포트를 적절한 곳에 위치시키면 외부와 어떤 통신이 일어나고 있는지 정확히 알 수 있고, 이는 레거시 코드를 다루는 유지보수 엔지니어에게 무척 소중한 정보이다.
웹 소켓을 통해 실시간 데이터를 사용자의 브라우저로 보낸다고 가정할 때 아래와 같은 포트가 반드시 필요하다.
만약 애플리케이션이 웹 어댑터에 능동적으로 알림을 줘야 한다면 의존성을 올바른 방향으로 유지하기 위해 아웃고잉 포트를 통과해야 한다.
위 그림을 보면 웹 소켓 컨트롤러는 인커밍 어댑터인 동시에 아웃고잉 어댑터가 되어 사용하고 있다.
애플리케이션이 웹 어댑터에 능동적으로 알림을 줘야 한다면 의존성을 올바른 방향으로 유지하기 위해서 아웃고잉 포트를 통과해야만 한다.
웹 어댑터의 책임
BuckPal 애플리케이션에서 REST API를 제공한다고 했을 때 웹 어댑터의 책임은 어디서 어디까지 일까?
- HTTP 요청을 자바 객체로 매핑
- 권한 검사
- 입력 유효성 검증
- 입력을 유스케이스의 입력 모델로 매핑
- 유스케이스 호출
- 유스케이스의 출력을 HTTP로 매핑
- HTTP 응답을 반환
보통은 웹 어댑터가 인증과 권한 부여를 수행하고 실패할 경우 에러를 반환한다.
그러고 나면 들어오는 객체의 상태 유효성 검증을 할 수 있다. 그런데 이전 포스트에서 입력 유효성 검증이 유스케이스 입력 모델의 책임이라고 했었다.
유스케이스 입력 모델은 유스케이스의 맥락에서 유효한 입력만 허용해야 한다. 그러나 여기서는 웹 어댑터
의 입력 모델에 대해 이야기 하고 있는 것이다.
유스케이스 입력 모델의 유효성 검증을 웹 어댑터에서도 구현해야 하는 것은 아니지만 웹 어댑터의 입력 모델을 유스케이스의 입력 모델로 변활할수 있다
는 것을 검증해야 한다.
HTTP와 관련된 것은 애플리케이션 계층으로 침투해서는 안된다. 우리가 바깐 계층에서 HTTP를 다루고 있다는 것을 애플리케이션 코어가 알게 되면 HTTP를 사용하지 않는 또 다른 인커밍 어댑처의 요청에 대해 동일한 도메인 로직을 수행 할 수 있는 선택지를 잃게 된다.
도메인과 애플리케이션 계층부터 개발하기 시작하면 이러한 계층은 자연스럽게 생기게 된다.
컨트롤러 나누기
웹 어댑터는 한 개 이상의 클래스로 구성해도 상관 없다. 하지만 같은 소속이라는 것을 표현하기 위해 같은 패키지 수준에 놓아야 한다.
또한 가능한 적게 만드는 것이 좋다.
BuckPal 애플리케이션의 Account 엔티티의 연산들을 예를 들었을 때 AccountController를 하난 만들어서 계좌에 관한 모든 요청을 받도록 만들 수 있다.
계좌 리소스와 관련 된 일이 하나의 클래스로 모여 있어 괜찮아 보이지만 단점이 많다.
먼저, 클래스의 코드는 적을 수록 좋다. 코드가 길어 질수록 파악하기가 어려워지고 테스트 코드 또한 파악하기 어려워 진다.
'DDD > CleanArchitecture' 카테고리의 다른 글
7장. 아키텍처 요소 테스트하기 (0) | 2023.05.13 |
---|---|
6장. 영속성 어댑터 구현하기 (0) | 2023.05.12 |
4장. 유스케이스 구현하기 (1) | 2023.05.12 |
3장. 코드 구성하기 (0) | 2023.04.28 |
2장. 의존성 역전하기 (0) | 2023.04.27 |