우리가 목표로 하는 아키텍처에서 외부 세계와의 모든 커뮤니케이션은 어댑터를 통해 이루어진다.
애플리케이션 코어에서 실시간 데이터를 웹 어댑터로 보내고, 웹 어댑터에서 사용자 브라우저로 데이터를 전송하기 위해서는 반드시 포트가 필요하다
01. HTTP 요청을 자바 객체로 매핑
02. 권한검사
03. 입력유효성 검증
04. 입력을 유스케이스의 입력 모델로 매핑
05. 유스케이스호출
06. 유스케이스의 출력을 HTTP로 매핑
07. HTTP 응답을 반환
웹 어댑터의 유효성 검증은 유스케이스 입력 모델로 변환 가능성을 검토 하는 것
웹 어댑터에 책임이 많아 보인다... 권한 검사는 스프링 필터에서 주로 하지 않나?
컨트롤러는 적은 것 보다 많은 것이 좋다
package buckpal.adapter.web;
@RestController
@RequiredArgsConstructor
class Accountcontroller {
private final GetAccountBalanceQuery getAccountBalanceQuery;
private final ListAccountsQuery listAccountsQuery;
private final LoadAccountQuery loadAccountQuery;
private final SendMoneyUseCase SendMoneyUseCase;
private final CreateAccountllseCase createAccountllseCase;
@GetMapping("/accounts")
List<AccountResource> listAccounts(){
}
@GetMapping("/accounts/{accountId}")
AccountResource getAccount(@PathVariable("accountld") Long accountld){
}
@GetMapping("/accoiints/{accountId}/balance")
long getAccountBalance(@PathVariable("accountId") Long accountld){
}
@PostMapping("/accounts")
AccountResource createAccount(@RequestBody AccountResource account){
}
@PostMapping("/accounts/send/{sourceAccountId}/{targetAccountId}/{amount}")
void sendMoney(
@PathVariable("sourceAccountId") Long sourceAccountld,
@PathVariable("targetAccountld") Long targetAccountld,
@PathVariable("amount") Long amount) {
}
}
계좌 리소스와 관련된 모든 것이 하나의 클래스에 모여있다
하나의 클래스에 몰아 넣는것은 데이터 구조의 재활용을 촉진 -> 단점이다
ex) AccountResource 에는 id가 들어 있을것이지만 create 시에는 이 id 값이 불필요하다
그렇기 때문에 SendMoneyController의 형태처럼 유스케이스를 반영하는 것이 좋다고 책에서는 말한다
웹 컨트롤러를 나눌 때는 모델을 공유하지 않는 여러 작은 클래스들을 만드는 것을 두려워하지 말자
-> 컨트롤러는 쪼개서
데이터 주도 설계를 벗어나기 위한 의존성 역전
서비스는 어플리케이션 포트를 호출할 뿐 영속성 어댑터를 호출하진 않는다
01. 입력을받는다
02. 입력을 데이터베이스 포맷으로 매핑한다
03. 입력을 데이터베이스로 보낸다
04. 데이터베이스 출력을 애플리케이션 포맷으로 매핑한다
05. 출력을반환한다
이러한 방식은 JPA 엔티티로 매핑하는 것이 들이는 노력에 비해 얻는 것이 많지 않은 일이 될 수 있다
-> JPA의 변경감지를 사용할 수 없다 -> 굳이 클린 아키텍처에서 JPA를 사용해야 될까?
넓은 인터페이스 보다는 특화된 인터페이스를 가져야 된다
위와 같이 도메인 클래스 하나당 영속성 클래스 하나를 둘 수 도 있다
애그리거트당 하나의 영속성 어댑터 접근 방식 또한 나중에 여러 개의 바운디드 컨텍스트(bounded context)의 영속성 요구사항을 분리하기 위한 좋은 토대가 된다
다른 맥락에있는 무언가가 필요할 경우에는 전용 인커밍 포트를 이용해야 된다.
트랜잭션은 하나의 특정한 유스케이스에 대해서 일어나는 모든 쓰기 작업에 걸쳐 있어야한다 -> 당연하지
-> 함께 롤백하기 위해서
도메인 코드에 플러그인처럼 동작하는 영속성 어댑터를 만들면 도메인 코드가 영속성과 관련된 것들로부터 분리되어 풍부한 도메인 모델을 만들 수 있다.
좁은 포트 인터페이스를 사용하면 포트마다 다른 방식으로 구현할 수 있는 유연함이 생긴다. 심지어 포트 뒤에서 애플리케이션이 모르게 다른 영속성 기술을 사용할 수도 있다.
포트의 명세만 지켜진다면 영속성 계층 전체를 교체할 수도 있다.