프로그래밍/기타

[클린 아키텍처 05] 웹 어댑터 구현하기

대인보우 2024. 9. 1. 17:20
반응형

 

<< 클린 아키텍처 05 >>

우리가 목표로 하는 아키텍처에서 

외부 세계와의 모든 커뮤니케이션은 어댑터를 통해 이루어진다!

 

의존성 역전

웹 어댑터는 '주도하는' 어댑터다.

외부로부터 요청을 받아 애플리케이션 코어를 호출하고 무슨 일을 해야하는 지 알려준다! 

 

제어흐름

adapter.in.web.Controller -> application.port.in.Port <-application.servcie.Service

 

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

서비스는 이 포트를 구현하고, 웹 어댑트는 이 포트를 호출할 수 있음

 

자세히 보면 의존성 역전 원칙이 적용된 걸 볼 수 있음! 

왜 어댑터와 유스케이스 사이 또 다른 간접 계층을 넣어야 할까?

애플리케이션 코어가 외부 세계와 통신할 수 있는 곳에 대한 명세가 포트이기 때문이다! 

 

웹 어댑터의 책임

웹 어댑터가 하는 일

1. HTTP 요청을 자바 객체로 매핑한다.

- 웹 어댑터는 URL, 경로, HTTP 메서드 등과 같이 특정 기준을 만족하는 HTTP 요청을 수신한다.

- HTTP 요청의 파라미터와 콘텐츠를 객체로 역직렬화 해야한다.

 

2. 권한을 검사한다.

- 인증과 권한 부여를 수행하고 실패할 경우 에러를 반환한다.

 

3. 입력 유효성을 검증한다.

- 유스케이스의 입력 모델과 다르게, 구조나 의미가 완전히 다를 수 있으므로 '웹 어댑터의 입력 모델'에 대한 유효성 검증을 수행해야 한다.

- 웹 어댑터의 입력 모델을 유스케이스의 입력 모델로 변환할 수 있다는 것을 검증해야 한다.

 

4. 입력을 유스케이스의 입력 모델로 매핑한다.

5. 유스케이스를 호출한다.

6. 유스케이스의 출력을 HTT로 매핑한다.

7. HTTP 응답을 반환한다.

 

웹 어댑터의 책임이 많긴 하지만 이 책임들을 애플리케이션이 신ㅇ경쓰면 안되는 것들이다.

HTTP와 관련된 것은 애플리케이션 계층으로 침투해서는 안된다.

우리가 바깥 계층에서 HTTP를 다루고 있다는 것을 애플리케이션 코어가 알게되면 HTTP를 사용하지 않는 또 다른 인커밍 어댑터의 요청에 대해 동일한 모메인 로직을 수행할 수 있는 선택지를 잃게 된다 

 

웹 어댑터와 애플리케이션 계층 간의 이러한 경계는 -> 유스케이스를 먼저 구현하면 자연스럽게 생기게 된다.

 

컨트롤러 나누기

컨트롤러는 몇개를 만들어야 할까?

 

1. 하나의 컨트롤러 클래스에 모두 때려넣는 방식

단점

- 클래스마다 코드는 적을수록 좋음

- 코드량이 많을수록 코드 파악에 난이도가 높아진다.

- 또한, 한 클래스에 대한 테스트 코드도 더 많아지게 된다!

- 데이터 모델의 재활용이 이루어짐 -> 어떤 함수에선 불필요한 내용이 포함될 수도 있다. (create시 id 필드 등등)

 

그렇기 때문에 별도의 패키지에 별도의 컨트롤러는 만들자

가급적 메서드와 클래스는 유스케이스를 최대한 반영해서 짓자

 

또한 각 컨트롤러의 전용 모델 클래스를 만들자 

- 재사용을 막을 수 있다.

 

또한, 컨트롤러명과 서비스명도 고려해보자

- Create 대신 Register 

 

다른 연산에 대한 동시작업이 쉬워진다

 

유지보수 가능한 소프트웨어를 만드는 데 어떻게 도움이 될까?

애플리케이션의 웹 어댑터는

- HTTP 요청을 애플리케이션의 유스케이스에 대한 메서드 호출로 변환

- 결과를 다시 HTTP로 변환하고 어떤 도메인 로직도 수행하지 않는 어댑터를 만들고 있다

 

애플리케이션 계층

- HTTP와 관련된 작업을 해서는 안된다 -> 웹 어댑터를 다른 어댑터로 쉽게 교체 가능

 

웹 컨트롤러를 나눌 때는 모델을 공유하지 않는 여러 작은 클래스들을 만드는 것을 두려워해서는 안된다!

작은 클래스들은 더 파악하기 쉽고, 더 테스트하기 쉬우며, 동시작업을 지원한다.

처음에는 공수가 더 들지라도 유지보수하는 동안에는 Gooooood~!!

 

반응형