프로젝트 구성 및 시작

유수민·2022년 11월 15일
0

DDD 프로젝트

목록 보기
3/7
post-thumbnail

📌계획

우선 현재 monolitic 구조로 되어 있는 ottsharing을 조금씩 분리하는 작업을 시작으로 ddd 프로젝트의 첫 시작을 하려고 한다.
만약 실제 서비스였다면, 기존에 운영되고 있는 것을 그대로 돌아가게 만들면서 점진적으로 발전하도록 해야하기 때문에 기존의 monolitic한 프로젝트를 legacy파일로 따로 두려고 한다. 그리고 우선적으로 회원가입을 이용해 간단히 틀을 만들려고 한다.

📌user 모듈 기본 구성 만들기

회원가입을 만든다고 할 때, 회원가입이라는 로직은 user 모듈에 속하기 때문에 우선적으로 user_api를 만들기로 결정하였다. 즉, user_api 패키지를 두고 domain, application, presentation, application을 만들었다.

각 layer마다 의존성과 설정이 다르기 때문에 각 layer마다 build.gradle이 필요하다.

📖domain

도메인 층은 도메인 또는 repository라는 객체만이 존재 한다. 즉, 여기서는 userV1이라는 객체가 존재한다. 또한, repository라는 저장하는 객체가 인터페이스 형태로 존재 한다. 도메인 층은 순수한 층이기 때문에 의존성을 최대한 극히 지양해야한다. 따라서 도메인층의 build.gradle에서 의존성이 없는 방향으로 구성하였다.

기존의 user 엔티티에서 현재 구성한 userV1 엔티티의 차이점이라고 한다면 어노테이션 활용도 지양하였다는 점 그러다보니 getter 메소드도 직접 만들고 생성자도 직접 만들면서, 객체가 생성될때마다 중복적으로 생성될 필요가 없는 id와 createdAt는 기존에 만들어진 것이 있다면 그대로 활용하도록 하였다.

도메인을 수정하면서 id의 타입을 instant에서 Long으로 수정하였고 LocalDateTime을 Instant로 수정하였다. Instant는 TimeZone을 정하여 활용하는 순간 localDateTime으로 변환해준다. 즉, 만약 사용자가 영국에 있으면 영국 기준의 시간을, 한국에 있으면 한국 기준의 시간을 정해준다.

📖application

어플리케이션 층은 오직 도메인의 존재만을 안다. 그래서 build.gradle에는 layer들 중 도메인만을 의존한다.

어플리케이션 층은 도메인층의 객체들을 모아 비지니스 로직을 만든다. 음 쉽게 생각하면 mvc구조의 서비스 역할을 한다고 생각하면 된다. ddd적인 용어를 쓰자면, 어플리케이션은 행동마다 processor클래스를 만들어야한다. 즉, usercase마다 만들어야 한다.

processor클래스에 execute 메소드와 command라는 static 클래스를 만들어주었다. execute메소드는 회원가입 기능으로 command에서 받은 값을 저장하는 역할을 한다.하나라도 못 받아오면 로직이 진행되지 않도록 트랜잭션을 걸어주었다.

command 클래스는 캡슐화를 위한 것인데, 따로 processor클래스밖에command 클래스를 만드는 방법과 proccessor클래스 안에 static 클래스로 만드는 방법이 있는데 전자의 방법은 processor클래스 로직을 알기 전에 command 내부 로직을 다 알아야 한다는 불편함이 있어서 나는 후자의 방법을 택했다.

📖presentation

웹과 관련있는 프레젠테이션 층은 오직 어플리케이션층의 존재만을 인식하기 때문에 의존성 또한 어플리케이션만 있다.

api호출을 받는 controller와 dto역할의 request객체를 만들어주었다.

Q. @Controller와 @Restcontroller와의 차이점?
@Controller는 view를 반환하기 위해 Model객체를 만들어 데이터를 담아 view를 찾는 역할이고 만약 데이터를 반환해야 한다면 @ResponseBody를 사용하여 Json형태로 데이터를 HTTp Response Body에 담아 반환한다.
@RestController는 @Controller에 @ResponseBody가 추가된 것이다. 따라서 Json형태로 객체 데이터를 HTTTP응답에 담아서 전송한다.

📖infrastructure

동작을 보장하기 위한 층으로 도메인, 어플리케이션, 프레젠테이션 층 모두에 의존한다.

도메인에 추상화 형태로 구현되었던 repsitory의 구현체를 여기서 만든다. 이때 나는 가장 의존성을 없애기 위한 시도가 많이 보인다고 생각한다. repository의 구현체를 repsitoryAdaptor로 이름이 지어진다. 현재는 인메모리로 메모리가 연결되어있지만 만약 adaptor마다 연결된 db(ex. MariaDB, MySQL)를 다르게 하고 싶다면 단지 밑에 그림의 빨간줄 한줄만 변경하면 된다는 사실!! 의존성을 벗어나는 것이 와닿는 순간이었다.

infastructure에는 repositoryAdaptor와 processor의 빈을 등록하는 역할인 config도 만들어주었다.

📌server

지금은 user_api 하나만 존재하지만 이제 앞으로 sharing_api, payment_api 등 다른 api들이 만들어질것이다. server모듈은 이 api들의 main이면서 서버로 올려주는 역할을 한다. 기존의 MSA gateway와 좀 다른 것이 server는 gateway와 달리 라우팅기능을 하지는 않는다. 한 서버로 올려서 잘 동작하도록 만드는 것이 server의 역할이다. 따라서 server모듈의 build.gradle은 legacy와 user-api를 다 의존하게 되어있다.

📌완성

아래 그림은 이제 기본적으로 구성된 구조이다.

이제 회원가입 로직에 대한 구현을 더 세밀하게 하는 것을 다음 할일이 되겠다.

profile
배우는 것이 즐겁다!

0개의 댓글