[Node.js] - TypeORM + TypeScript + Express 개발환경 세팅
🐳 Layered Architecture의 구성요소
Layered Architecture에는 크게 네 가지 Layer가 있습니다.
1. Presentation Layer
2. Business Logic Layer ( Domain Model )
3. Persistence Layer ( Data Access Layer )
4. Database Layer
각각의 계층과 역할에 대해서는 이 링크에서 설명해 놓았습니다.
이론적으로는 레이어드 아키텍쳐에 대해서 이해하겠으나 실제로 적용하는 것은 다른 문제였다.
Entity, Repository, Service, Controller 등 다양한 개념이 등장했고 이것들이 어느 계층에 속하는지도 개념이 이해가 되지 않아 이 개념을 적립하는데 많은 시간이 소요 됐다.
같은 고민을 하는 분들을 위해 각각의 구성요소가 어디에 속하는지 한 번 알아보겠습니다
1. Controller
Controller의 경우 Presentation Layer로 보는 견해도 있고 Service Layer에 속한다고 보는 견해도 있습니다.
( Service Layer는 아래에서 설명하겠습니다. 계층의 순서대로 내려가기 위해 Controller 부터 설명하는 점 이해 부탁드립니다. )
이에 대해 Martin Fowler는 Presentation Layer 안에 Controller와 View가 존재한다고 말합니다.
https://martinfowler.com/eaaDev/SupervisingPresenter.html
이러한 Controller의 역할로는 Client의 요청을 서비스 레이어에 전달하는 역할을 해줍니다.
2. Service
Service는 Controller로부터 Client의 request를 받아 요청을 처리해 주는 역할을 수행합니다.
그렇다면 발생하는 궁금증은 Business Logic Layer ( Domain Model ) 와 역할이 같지 않냐는 것입니다.
실제로 둘은 비슷한 역할을 수행하지만 어디에 초점을 맞췄느냐가 다릅니다.
Business Logic Layer는 도메인의 규칙과 개념을 처리하는데 중점을 둔 계층입니다. Single Responsibility Principle 처럼 하나의 도메인에 대해 하나의 책임을 가지는 비지니스 로직을 가지게 설계합니다.
하지만 실제 프로젝트에서는 하나의 비지니스 로직만으로 해결할 수 없는 문제들도 존재합니다.
여러 도메인에서 데이터를 가지고 와야 한다는 뜻입니다.
Service Layer는 이러한 문제들을 해결하기 위해 만들어진 계층입니다.
Service Layer는 도메인에 초점을 맞추기 보다는 Client의 요청을 처리하는데 초점을 맞춘 계층으로 여러 비지니스 레이어를 가져와 다뤄 Client의 요청을 처리해 줍니다.
요약하면
Conroller -> Service -> Business Layer 라고 생각하면 될 것 같습니다.
3. Entity와 Reposiotry
Entity와 Repository는 Business Layer ( Domain Model )에 속하는 도메인 모델입니다.
Entity는 도메인의 핵심 개념을 나타내는 객체입니다. 그리고 이 엔티티에는 엔티티의 상태와 행동을 모두 저장하는 것이 좋습니다.
이는 Martin Fowler의 TellDontAsk 라는 포스트를 읽어보면 더 잘 이해가 가실 겂니다.
Martin Fowler는 위의 포스트에서 데이터와 로직을 함께 둠으로써 상태에 대해 물어보는 것이 아니라 객체가 말 할 수 있게 하라고 합니다. 이는 OOP가 객체 안에 상태와 행동을 같이 캡슐화 하는 원리를 사용하는 것을 생각한다면 당연한 일일 것입니다.
Repository는 엔티티를 다룰 수 있게 데이터 액세스 작업을 수행하는 클래스 입니다. 도메인 객체는 이 레포지토리를 사용해 데이터베이스에 접근할 수 있게 해줍니다. 이러한 레포지토리는 Domain Model이기도 하지만 데이터 엑세스 레이어의 일부라고도 생각할 수 있을 것 같습니다.
이러한 다양한 요소들이 결합하여 Layered Architecture를 구성하고 있기 때문에 각각의 역할에 대해서 이해하는 것이 중요합니다.
🐳 디렉토리 구조
레이어드 아키텍처의 관점에서 디렉토리 구조를 보면 위의 설명한 것처럼 디렉토리를 크게 아래와 같이 구성하였습니다.
1. 컨트롤러
2. 서비스 레이어
3. 엔티티/레포지토리
그리고 data-source.ts는 typeORM을 사용하면 기본으로 생기는 파일로 데이터베이스에 접근하는 AppDataSource를 생성해 주는 파일입니다. 이 파일을 데이터 액세스 레이어라고 생각한다면 총 4개의 계층으로 구성했다고 볼 수 있습니다.
🐳 회고
설명해 보니 별거 없는 것 같은 구성이지만 실제로 이 디렉토리를 구성하기 위해서 꼬박 하루를 사용했습니다 ...
MVC 패턴과 Layered Architecture의 상관관계는 어떻게 되는 건지 Controller에는 뭐가 들어가야 하는지... 기존에 Express에서 사용하던 router.js는 어떻게 해야 하는지 등 정말 많은 문제들이 있었습니다. 그래도 용어 하나 하나 짚어 가며 어느 계층에 속하고 어떤 역할을 하는지 정리하니 도움이 됐습니다.
정리하고 보니 Controller, Repository처럼 경계가 모호한 친구들도 있었습니다. 그러면서 생각한 건 이 친구가 레이어드 아키텍처의 정확히 어떤 계층에 존재한다고 분류하는 것보다 내가 사용하려는 컴포넌트들의 상관 관계와 의존 관계가 어떻게 되고 누가 더 상위 계층에 있는지를 파악하는 것이 중요하다는 생각이 들었습니다. 그리고 당연히 각 컴포넌트들의 역할을 이해하는 것은 필수이구요.
큰 산을 넘었으니 이제는 레이어드 아키텍처스럽게 OOP스럽게 코드를 구현해 보겠습니다.
'Node.js' 카테고리의 다른 글
[PrismaORM] upsert 사용 시 Unique constraint failed on the fields 문제 해결 (0) | 2024.08.23 |
---|---|
[ExpressJS] Javascript로 Enum 사용하기 - 오픈카톡방 공유 후기 (0) | 2024.01.20 |
TypeORM v0.3에서 Repository 구현 및 테스트 코드 구현 (0) | 2023.07.08 |
Typescript로 Jest 사용하기 (0) | 2023.07.06 |
TypeORM + TypeScript + Express 개발환경 세팅 (0) | 2023.07.03 |