Node.js/Express 프로젝트의 구조를 일반적으로 한개의 레포지토리에서 관리하는 모노리포 구조로 작성했다.
모노리포와 멀티리포 비교는 아래 블로그를 참고하길 바란다.
https://tech.buzzvil.com/handbook/multirepo-vs-monorepo/
구조설명
src 디렉토리 내에 다양한 서브 프로젝트들이 위치하고 있으며, 각각의 서브 프로젝트들은 독립적인 기능을 가지고 있거나 연관된 기능들을 묶어놓은 구조이다.
아래는 간단한 예시를 작성했다.
├── package-lock.json
├── package.json
├── src
│ ├── @types
│ │ ├── api
│ │ └── exception
│ ├── bin
│ ├── config
│ ├── database
│ │ ├── entity
│ │ ├── enum.ts
│ │ ├── namingStrategy
│ │ ├── repository
│ ├── libs
│ │ ├── exception
│ │ ├── logger
│ │ ├── mail
│ │ ├── storage
│ ├── middlewares
│ └── routes
│ ├── user
│ │ ├── controller.ts
│ │ ├── index.ts
│ │ └── service.ts
│ ├── home
│ │ ├── banner
└── tsconfig.json
디렉토리 설명
- src: 소스 코드가 위치하는 최상위 디렉토리
- @types: TypeScript 타입 정의 파일들이 위치하는 디렉토리로, api와 exception에 관련된 타입 정의 파일들이 있음
- bin: 실행 가능한 스크립트나 설정 파일 등이 위치할 수 있는 디렉토리
- config: 설정 파일들이 위치하는 디렉토리로, 환경 설정과 관련된 파일들이 존재
- database: 데이터베이스 관련 파일들이 위치하는 디렉토리로, 주로 엔티티, 열거형(enum), 리포지토리 등의 파일들이 존재
- libs: 라이브러리와 유틸리티 함수들이 위치하는 디렉토리로, 예외 처리, 로깅, 메일, 파일 저장 등의 기능들을 모듈화하여 재사용할 수 있음
- middlewares: Express 미들웨어 함수들이 위치하는 디렉토리로, 요청과 응답 사이에서 중간 처리를 담당하는 함수들이 들어감
- routes: Express 애플리케이션의 라우트(경로)들이 위치하는 디렉토리. 서버의 다양한 엔드포인트에 대한 라우팅 처리를 담당하는 파일들이 존재하는 디렉토리
이렇게 잘게 나누는 이유는 무엇일까?
이러한 디렉토리 모노리포 구조를 사용하면 코드를 모듈화하고 관련 기능들을 기능 단위로 분리하여 유지보수와 코드 구조화를 용이하게 할 수 있기 때문이다.
Entity와 Repository란?
엔티티와 레포지토리는 ORM과 Entity, Repository 패턴은 복잡한 데이터베이스 로직을 다루는데 도움이 되며, 데이터베이스 관련 코드를 추상화하여 애플리케이션의 유연성과 유지보수성을 높이는데 사용되지만, 의미하는 바가 조금 다르다.
- Entity
- Entity는 데이터베이스 테이블과 일치하는 자바스크립트/타입스크립트 클래스를 말함
- 데이터베이스의 테이블과 컬럼 구조를 반영하여 프로그래밍 언어에서 사용하기 위해 정의
- 예를 들어, 사용자(User) 테이블이 있다면, 해당 테이블과 일치하는 User 클래스가 entity로 정의
- Entity 클래스는 ORM을 사용하여 데이터베이스의 레코드를 객체로 매핑하는데 사용. ORM은 데이터베이스 테이블의 레코드를 객체로 변환하고, 객체를 다시 데이터베이스 레코드로 변환하는 작업을 단순화
- ORM을 사용하면 데이터베이스 스키마 변경이 있을 때도 비교적 쉽게 코드를 관리할 수 있으며, 데이터베이스와 프로그래밍 언어 간의 변환 작업을 ORM 라이브러리가 처리
- Repository
- Repository는 데이터베이스와의 상호작용을 추상화하는 계층
- Entity 클래스에 대한 CRUD(Create, Read, Update, Delete) 작업을 수행하는 메서드를 제공
- 이렇게 데이터베이스와의 상호작용을 Repository에서 처리하면, 서비스 레이어 또는 비즈니스 로직에서 데이터베이스 접근을 직접 다루지 않아도 되므로 더 추상화된 코드를 작성할 수 있게 해줌
- 또한, 데이터베이스 관련 로직들을 한 곳에 모으므로 코드 중복을 줄이고 유지보수성을 향상시켜줌
- Repository는 데이터베이스 테이블과 1:1로 매칭되는 경우가 많지만, 좀 더 복잡한 로직을 다루기 위해 Entity와는 다른 구조로 설계되기도 함
Routes
routes 디렉토리 아래에 user라는 서브 디렉토리를 만들고, 해당 서브 디렉토리 내에 controller.ts, index.ts, service.ts 파일들을 나누어 놓는 이유는 코드를 모듈화하고 애플리케이션의 구조를 단순화하는 데 있다.
- controller.ts
- controller.ts 파일은 Express 애플리케이션의 라우트 핸들러를 정의하는 역할
- 클라이언트로부터 요청이 들어왔을 때 어떤 동작을 수행할지 정의하는 파일이며, 해당 경로에 대한 요청을 처리하고 응답을 반환
- 이렇게 controller.ts 파일을 별도로 분리하여 관리하면, 애플리케이션의 라우트 처리 로직이 모듈화되어 유지보수가 용이해짐
- index.ts
- index.ts 파일은 서브 라우터의 진입점 역할
- index.ts 파일은 controller.ts와 service.ts를 가져와서 라우터를 설정하고 Express 애플리케이션에 등록하는 역할
- 이렇게 index.ts 파일을 만들면, 서브 라우터를 더욱 구조적으로 관리할 수 있음
- service.ts
- service.ts 파일은 controller.ts에서 필요한 비즈니스 로직을 처리하는 서비스 레이어의 역할
- 비즈니스 로직은 데이터베이스 조회, 데이터 처리, 외부 API 호출 등과 같이 서버의 핵심 로직을 담당
- controller.ts에서는 클라이언트의 요청을 받아 이러한 service.ts 파일에서 정의한 로직을 호출하고 결과를 응답으로 반환
- service.ts 파일을 별도로 분리하여 관리하면, 코드의 재사용성과 유지보수성을 높일 수 있음
이렇게 파일들을 서브 디렉토리 내에 나누어 놓으면, 코드를 논리적으로 구분하고 각 모듈을 독립적으로 관리할 수 있다. 또한, 팀 협업 시에도 각각의 모듈을 담당할 수 있는 구조를 제공하여 개발자들이 특정 영역에 집중하고 작업할 수 있게 만들어준다. 이러한 모듈화된 구조는 애플리케이션이 커지고 복잡해질 때 특히 유용해지므로 미리 구축해두는 것이 좋다.
'JaveScript > ExpressJS' 카테고리의 다른 글
dayjs 사용해서 나이 계산하기 (0) | 2023.12.14 |
---|---|
ts-jenum으로 Enum객체 활용 (0) | 2023.12.13 |
expressjs + typeorm 0.3 세팅 후 사용법 (1) | 2023.12.12 |
morgan 세팅 (0) | 2023.11.30 |
ExpressJS 프로젝트 세팅하기 (0) | 2023.07.18 |