EMP 프로젝트 소개
🎵 Emotional Mood Player (EMP)
감정과 가사 기반의 맞춤형 음악 추천 서비스
📌 프로젝트 소개
Emotional Mood Player는 사용자의 감정 상태와 선호하는 가사를 기반으로 개인화된 플레이리스트를 생성해주는 음악 추천 서비스입니다. 자연어 처리 기술을 활용하여 가사의 의미를 분석하고, 사용자의 감정 상태에 맞는 최적의 음악을 추천합니다.
주요 기능
- 감정 기반 음악 추천: 현재 감정 상태에 따른 맞춤형 플레이리스트 생성
- 가사 기반 음악 추천: 선호하는 가사 스타일과 유사한 곡들을 추천
- 플레이리스트 관리: 생성된 플레이리스트 저장, 수정, 삭제 기능
- 음악 재생: Spotify API를 통한 음악 스트리밍 서비스 제공
- 소셜 공유: 생성된 플레이리스트 공유 기능(개발 예정)
🛠 기술 스택
Frontend
1
2
3
4
5
- React 18.3.1
- Recoil (상태 관리)
- Axios (HTTP 클라이언트)
- React Router DOM
- CSS Modules
Backend
1
2
3
4
5
6
Node.js
Express.js
Prisma (ORM)
MySQL
Passport.js (인증)
Winston (로깅)
DevOps & Tools
1
2
3
4
ESLint
Prettier
Nodemon
Cross-env
프로젝트 구조
1
2
3
├── frontend/ # 리액트 기반 프론트엔드
├── model_server/ # ML 모델 서버
└── server/ # Express 기반 백엔드
🔑 주요 기술적 특징
백엔드 아키텍처
3-Tier Architecture 적용
1
2
3
Presentation Layer (Controllers)
Business Logic Layer (Services)
Data Access Layer (Models)
보안
1
2
3
Passport.js를 활용한 OAuth2.0 인증
Session 기반 사용자 인증
CORS 설정을 통한 보안 강화
데이터베이스
1
2
Prisma ORM을 활용한 타입 안전성 보장
마이그레이션 기반 데이터베이스 버전 관리
에러 처리
1
2
전역 에러 핸들러를 통한 일관된 에러 응답
Winston 로거를 활용한 체계적인 로그 관리
🚀 시작하기
요구사항
1
2
3
4
Node.js 18 이상
MySQL 8.0 이상
Spotify Premium 계정 (음악 재생 기능)
Spotify Preminum 계정이 아닐 경우 Playlist 생성만 가능
추가 고도화 진행 사항
TypeScript 도입 3차 프로젝트는 프레임워크로 NEST.JS를 도입해서 사용하고싶었으나 벡엔드 포지션 팀원이 많기도하고 구현 능력이 달라 포기했던 부분이 있었다.
진행은 Express로 만들고 JS까지만 사용해서 TS로의 전환까지 해보려고한다.
프레임워크 현재 프로젝트 구조는 관심사 분리/레이어 구분 이정도 원칙만을 사용해서 구현했었다. 1번의 타입스크립트로는 OOP 구현이 어렵기도 하고 의존성 주입(Dependency Injection, DI)이 쉬운 NestJS가 있기 때문에 OOP 구현은 NestJS 프로젝트를 할때 구현해보자는 생각이 있어 고도화는
TypeScript + Express로 진행하려한다.디렉토리 구조 EMP 프로젝트는 기능별 구조(Feature-based)르 벡엔드 폴더 구조를 구성했는데, 이전부터 관심이 있었던 DDD(Domain-Driven Design)까지 구현을 해보고싶었다. 현재까지 구현된 기능들에서 커뮤니티(예로 자신이 만든 플레이리스트를 공유하는 게시판이라거나) 여러 기능들을 추가적으로 구현하기에 좋을 것 같다는 생각을 가지고 있었는데 DDD까지 구현하기에는 어려운 부분이 있어 약간의 원칙들만 가져와서 구현을 해보려고 한다. 여기에는 2번에서 언급한 Exrpess의 OOP의 구현 난이도도 한 몫했다.
아래는 비교를 위해서 약간의 예를 가져와봤다.
feature-based
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
src/ ├── controllers/ │ ├── authController.ts │ ├── playlistController.ts │ └── userController.ts ├── services/ │ ├── authService.ts │ ├── playlistService.ts │ └── userService.ts ├── routes/ │ ├── authRoutes.ts │ ├── playlistRoutes.ts │ └── userRoutes.ts ├── models/ │ └── index.ts └── utils/ ├── errors.ts └── logger.tsfeature-based 구조는 레이어 별 코드 분리로 모듈화를 하는 방식으로 현재 벡엔드 코드 상태다.
관심사 분리(controller와 service 분리), 단일 책임 원칙 등을 지키려고 노력했었으나, 팀원들과 협업을 하면서 비즈니스 코드 중복과 복잡성이 늘어날 확률이 눈에 보이기 시작했다.
역시 협업의 처음에는 컨벤션을 견고히 잡아두어야한다는 말이 이해가 간다.
문제를 해결할 겸 여러가지 방식과 기능 추가를 고려해두고 구조 방식을 찾아보았다.
DDD(Domain-Driven Design)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
src/ ├── modules/ │ ├── auth/ │ │ ├── domain/ │ │ │ ├── entities/ │ │ │ └── value-objects/ │ │ ├── application/ │ │ │ ├── use-cases/ │ │ │ └── services/ │ │ ├── infrastructure/ │ │ │ ├── repositories/ │ │ │ └── providers/ │ │ └── interfaces/ │ │ ├── controllers/ │ │ └── routes/ │ │ │ └── playlist/ │ ├── domain/ │ ├── application/ │ ├── infrastructure/ │ └── interfaces/ │ └── shared/ ├── infrastructure/ └── domain/
DDD구조는 비즈니스 도메인 별로 개발을 진행해야하는데, 명확한 코드계층을 통해서 도메인 별로 관련된 요소를 해당 모듈에 모아서 작성해야한다. 작년 우아콘에서 DDD 세션이 있었는데 아무래도 대규모 서비스들이 채택하는 이유가 있다. 각각의 서비스의 응집도와 확장성을 모두 챙길 수 있으니 이해가 간다.
여담이지만 OOP의 확장이라는 말이 있는데 아직까지는 잘 모르겟다.
정리하자면
- 비즈니스 도메인 중심: 각 도메인의 로직이 하나의 모듈에 있다.
- 아키텍쳐: presentation layer, Application, Domain, Infrastructure 계층으로 구성
- 도메인 모델이 명확함(역시 비즈니스 도메인에 맞춰서 개발하다보니, 구현도 쉽지 않을까 아니겠지만ㅎㅎ)
결론적으로는 아주 약간만 DDD에서 채용하기로 했다. DDD는 공부할게 많고 아직까지는 부족하다생각되어서 복잡한 로직을 생각해보고 구현할 일이 생긴다면 그때 구현해보겠다.
feature-based로 진행을 하겠지만 약간의 도메인 정리 정도로 방향을 잡았다.
- Domain별 분리
- 공통코드(type, middleware, utils)들을 shared로 정리
- Infra 관련 코드들(DB, config)들 별도로 분리
3가지를 잘 맞춰서 진행해보자!
추가) 진행상황 추가
DDD를 채용하기로 했지만 우아콘2024에 가서 DDD에 대한 세션을 들었다. 역시나 생각하던 걸림돌이기도했고 프로젝트 구조만을 약간 채용하는 것만으로는 많이 부족하다고 생각해서 결국 기능별 구조로 변경했다.
현재 코드 구조는 아래와 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
├── front
│ ├── public
│ └── src
├── model_server # 파이썬 AI 모델 서버(FAST API)
└── server
├── prisma
└── src
├── @types
├── auth # 인증 관련 기능
├── config # 설정
├── infrastructure # 인프라 기반 코드
│ ├── auth # 인증 인프라
│ ├── database # DB 연결 관리
│ ├── session # 세션 관리
│ ├── swagger # API 문서 스웨거
│ └── types
├── middlewares # 인증, 에러, 유효성 검사 미들웨어
│ └── validators
├── playlists # 플레이리스트 관련 기능
├── routes # 라우터 매니저 및 설정
├── shared # 공통 타입과 유틸리티
│ ├── types
│ └── utils
└── users # 계정 관련 기능