1. Express-Generator 기본 구조: 빠른 시작을 위한 뼈대
express-generator가 제공하는 구조는 Express 애플리케이션의 가장 기본적인 뼈대이며, 신속한 개발 착수에 초점을 맞춘다.
bin/www: 서버 실행 스크립트이다. Node.js HTTP 서버를 구동하고 특정 포트를 리스닝하는 역할을 담당하며, 애플리케이션의 '설정'(app.js)과 '실행'을 분리하는 구조이다.public: 정적 파일 디렉토리이다. 이미지, 클라이언트 사이드 JavaScript, CSS 등 브라우저가 직접 접근하는 파일들을 보관한다.routes: 라우팅 처리 디렉토리이다. URL 경로에 따라 클라이언트의 요청을 어떻게 처리할지 정의하는 로직이 위치한다.views: 템플릿 파일 디렉토리이다. Pug, EJS 등 서버 사이드에서 동적으로 HTML을 생성하기 위한 템플릿 파일들을 관리한다.app.js: Express 애플리케이션의 핵심 설정 파일이다. 미들웨어 로드, 라우터 연결, 템플릿 엔진 설정 등 앱의 전반적인 구성을 담당한다.package.json: 프로젝트의 메타데이터 파일이다. 프로젝트 정보, 의존성 라이브러리 목록, 실행 스크립트 등을 정의한다.
2. 나의 확장 구조: 관심사 분리(SoC)의 적용
기본 구조에 추가된 디렉토리들은 코드를 '책임'에 따라 분리하기 위한 것이며, 이는 코드 품질을 향상시키는 중요한 단계이다.
constants: 상수 관리 디렉토리이다. 애플리케이션 전역에서 사용되는 고정값(JWT 키, 상태 메시지 등)을 모아 하드코딩을 방지하고 중앙에서 관리하기 위함이다.database/connection: 데이터베이스 연결 관리 디렉토리이다. 데이터베이스 연결 설정 및 관련 로직을 한곳에 모아 관리의 편의성을 높인다.modules(controllers,services): 핵심 비즈니스 로직 디렉토리이다. 이는 MVC 또는 유사 아키텍처 패턴을 적용한 것이다.controllers: HTTP 요청과 응답(Request/Response)을 직접 처리하는 계층이다. 사용자 인터페이스와 비즈니스 로직 사이의 중재자 역할을 한다.services: 실질적인 비즈니스 로직을 수행하는 계층이다. 데이터 가공, 계산 등 핵심 작업을 처리하며 데이터베이스와 상호작용한다.
utils: 범용 유틸리티 함수 디렉토리이다. 특정 비즈니스 로직에 종속되지 않고 여러 곳에서 재사용될 수 있는 함수(인증, 에러 핸들링 등)를 관리한다.
3. 제안된 발전한 구조
더 복잡한 애플리케이션에 대응하기 위해 구조를 더욱 세분화하여 확장성, 안정성, 협업 효율성을 높일 수 있다.
config: 환경 설정 관리 디렉토리이다. 개발, 테스트, 프로덕션 환경별로 다른 설정(DB 정보, API 키 등)을 분리하고,.env파일을 통해 민감 정보를 안전하게 관리한다.repositories(또는models): 데이터 접근 계층이다. 데이터베이스 CRUD(생성, 조회, 수정, 삭제) 작업을 전담한다. Service 계층은 Repository를 호출하여 데이터를 처리함으로써, 비즈니스 로직에만 집중할 수 있게 된다.middleware: 미들웨어 디렉토리이다. 인증, 권한 검사, 로깅 등 여러 라우터에서 공통으로 사용되는 처리 로직을 중앙에서 관리하여 역할을 명확히 한다.tests: 테스트 코드 디렉토리이다. 단위 테스트, 통합 테스트 코드를 작성하여 코드의 안정성과 품질을 보장한다.docs: API 문서 디렉토리이다. Swagger 같은 도구를 사용하여 API 명세를 문서화함으로써 팀원 간의 원활한 협업을 지원한다.
4. 최종 Express 구조와 Nest.js 구조의 비교
잘 설계된 발전된 Express 구조는 개념적으로 Nest.js와 매우 유사하다. 하지만 두 프레임워크는 구현 방식과 철학에서 근본적인 차이점을 가진다.
| 항목 | 발전된 Express.js 구조 | Nest.js 구조 |
|---|---|---|
| 프레임워크 철학 | 무규칙적 (Un-opinionated) | 규칙적 (Opinionated) |
| 개발자가 직접 도구(ORM, Validator 등)를 선택하고 아키텍처를 구축해야 한다. 자유도가 높지만, 개발자의 역량에 대한 의존도가 크다. | CLI, 모듈 시스템, 의존성 주입 등 완전한 개발 프레임워크를 제공한다. 개발자는 정해진 패턴을 따르므로 코드의 일관성과 조직력이 높다. | |
| 주요 언어 | JavaScript (ES6+) | TypeScript |
| TypeScript 사용이 가능하나, 개발자가 직접 컴파일 환경을 설정해야 한다. | 프레임워크 자체가 TypeScript의 특성(데코레이터, 타입 시스템)과 깊게 통합되어 있어 언어의 장점을 극대화할 수 있다. | |
| 아키텍처 핵심 | 수동으로 구현된 모듈화 | 내장된 모듈 시스템 (Module System) |
'폴더' 구조를 통해 기능 모듈을 구성하고, require/import로 의존성을 수동 관리한다. |
@Module() 데코레이터를 통해 각 모듈의 범위(Controller, Service 등)를 명확히 정의하고 의존성을 관리하여 진정한 '캡슐화'를 구현한다. |
|
| 의존성 관리 | 수동 인스턴스화 및 전달 | 의존성 주입 (Dependency Injection, DI) |
Service에서 Repository를 사용하려면 일반적으로 new Repository()와 같이 직접 인스턴스를 생성하고 전달해야 한다. |
프레임워크에 내장된 DI 컨테이너가 클래스의 생성자를 분석하여 의존성을 자동으로 '주입'해준다. 이는 모듈 간의 결합도를 크게 낮춘다. | |
| 코드 스타일 | 명령형 (Imperative) | 선언형 (Declarative) |
router.get('/users', userController.getUsers)와 같이 함수 호출을 통해 라우팅 등을 직접 정의한다. |
@Controller(), @Get() 같은 데코레이터를 사용하여 클래스나 메서드의 역할을 '선언'하므로 코드가 더 간결하고 직관적이다. |
|
| CLI 도구 | express-generator |
nest-cli |
| 프로젝트 초기 골격을 생성하는 기본적인 기능만 제공한다. | 프로젝트 생성은 물론, 모듈, 컨트롤러, 서비스 등 표준화된 코드 파일을 자동으로 생성하고 모듈에 등록까지 해주어 생산성이 매우 높다. |
요약
발전된 Express 구조는 개발자가 경험과 규범을 통해 수동으로 구축한 체계적인 '형태'이다. 이는 애플리케이션의 각 부분을 책임에 따라 분리하여 코드의 유지보수성을 높인 결과이다.
반면, Nest.js는 프레임워크 차원에서 모듈 시스템, 의존성 주입 등의 강력한 도구를 기본적으로 제공한다. 개발자는 '바퀴를 재발명'할 필요 없이 자연스럽게 높은 응집도와 낮은 결합도를 가진 코드를 작성하게 되며, 이는 아키텍처의 '정신'까지 갖춘 것이다.
따라서 현재의 Express 구조에서 Nest.js로 전환하는 것은, '수동 관리'에서 '프레임워크를 통한 자동화된 관리'로의 전환을 의미한다. 이를 통해 개발자는 비즈니스 로직에 더욱 집중할 수 있고, TypeScript가 제공하는 타입 안정성과 개발 효율성의 이점을 온전히 누릴 수 있게 된다.
'Programmers' 카테고리의 다른 글
| [27일차]Node.js 프로젝트 구조, 암호화 인증 시스템 (0) | 2025.10.17 |
|---|---|
| [과제]회원가입, 로그인 API 구현 흐름, 결과 (0) | 2025.10.17 |
| [25일차]프로젝트 설계 후기, 방법론 정리 (0) | 2025.10.15 |
| [24일차]API 설계 보고서 (0) | 2025.10.14 |
| [23일차] 2차, 3차 프로젝트 개발 계획서 (0) | 2025.10.13 |