5장. 웹 어댑터 구현하기

2023. 5. 12. 15:47DDD/CleanArchitecture

소개

만들면서 배우는 클린 아키텍처 책을 읽고 정리하며 소감을 적는 포스트입니다.

웹 어댑터 구현하기

UI나 다른 시스템에서 애플리케이션을 호출하는 방식으로 상호작용하는 HTTP API가 웹 어댑터에 해당 됩니다.

의존성 역전

아래의 그림은 웹 어댑터와 관련된 아키텍처 요소(어댑터 자체와 애플리케이션 코어와 상호작용 하는 포트)에 조금 더 초점을 맞춘 그림이다.

인커밍 어댑터는 애플리케이션 서비스에 의해 구현된 인터페이스인 전용 포트를 통해 애플리케이션 계층과 통신한다.

adapter.in.web주도하는 어댑터이다. 제어 흐름은 웹 어댑터에 있는 컨트롤러에서 애플리케이션 계층에 있는 서비스로 흐른다.

애플리케이션 계층은 웹 어댑터가 통신할 수 있는 특정 포트를 제공한다.

위 그림은 의존성 역전 원칙이 적용되어 있는데 왜 아래와 같이 직접 호출 하지 않는 것일까??

포트 인터페이스를 삭제하고 서비스를 직접 호출할 수 있다.

애플리케이션 코어가 외부 세계와 통신 할 수 있는 곳에 대한 명세가 있는 포트이기 때문이다. 포트를 적절한 곳에 위치시키면 외부와 어떤 통신이 일어나고 있는지 정확히 알 수 있고, 이는 레거시 코드를 다루는 유지보수 엔지니어에게 무척 소중한 정보이다.

웹 소켓을 통해 실시간 데이터를 사용자의 브라우저로 보낸다고 가정할 때 아래와 같은 포트가 반드시 필요하다.

만약 애플리케이션이 웹 어댑터에 능동적으로 알림을 줘야 한다면 의존성을 올바른 방향으로 유지하기 위해 아웃고잉 포트를 통과해야 한다.

위 그림을 보면 웹 소켓 컨트롤러는 인커밍 어댑터인 동시에 아웃고잉 어댑터가 되어 사용하고 있다.

애플리케이션이 웹 어댑터에 능동적으로 알림을 줘야 한다면 의존성을 올바른 방향으로 유지하기 위해서 아웃고잉 포트를 통과해야만 한다.

웹 어댑터의 책임

BuckPal 애플리케이션에서 REST API를 제공한다고 했을 때 웹 어댑터의 책임은 어디서 어디까지 일까?

  1. HTTP 요청을 자바 객체로 매핑
  2. 권한 검사
  3. 입력 유효성 검증
  4. 입력을 유스케이스의 입력 모델로 매핑
  5. 유스케이스 호출
  6. 유스케이스의 출력을 HTTP로 매핑
  7. 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