nodejs

Building node API server based on DDD architecture

Domain Layer

Domain 레이어는 각 서브 도메인 마다 model, service, repository를 가지며 다음과 같은 역할을 수행한다.

- Model

​ 해당 도메인의 모델링이 정의되고, 해당 도메인 내에서의 항상성과 유효성을 담당한다.

- Service

​ 주로 여러 도메인을 아우르는 로직을 처리한다.

- Repository

​ 도메인 단위로 DB 입출력을 담당하며, 실제 구현은 infra layer의 repository implementation에서 이루어 지며, interface만 정의되어 있다.

API Layer

도메인의 서비스들을 조합하며 엔드 유저 레벨에서의 기능수행이 이루어 진다.

가령 특정 재화를 구매함에 따라 결제를 수행하는 어플리케이션이 있다면 본 api 레이어에는 ‘결제’와 같은 엔드 유저 레벨에서의 함수가 들어가며, 결제 데이터 생성, 구매자의 감소 등과 같은 로직은 도메인의 모델 및 서비스 레벨에서 처리된다.

Infra layer

도메인의 비즈니스 로직들이 잘 수행될 수 있도록 DB, http 라우터 등 외부 환경을 다루는 실제 구현이 이루어 진다.

본 레이어에서 도메인의 repository interface에 정의된 함수들을 실제로 구현하며, express router를 활용하여 외부 요청에 대한 라우팅을 수행한다.

또한 본 레이어에는 middleware, auth guard, errorHandler 처럼 도메인에 접근하기 전에 전처리되거나 비즈니스 로직 이후 클라이언트에게 반환할 반환값에 대한 후처리 로직이 들어간다.

auth guard 는 decorator 를 사용하여 제작되었다.

Branching Model

모든 작업 내용은 feature/[브랜치 명] 에서 작업하고, dev 서버에 배포하기 위한 버전을 develop 브랜치에 푸시한다.

Release 브랜치에서 develop 브랜치를 pull 하면서 코드리뷰를 진행하고 모든 코드리뷰 사항이 반영되면 release 브랜치에 머지된다.

release 브랜치에서 스프린트 및 일정관리, 테스트 작업을 진행하며 안정화되면 master 브랜치로 push 하고 서비스 배포한다.

- Master: 실제 서비스 배포를 위한 브랜치

- Release: 개발 진행의 경과가 되는 브랜치로 QA 및 일정관리의 지표가 된다.

- Develop: 각 개발자들이 실시간으로 머지하는 브랜치로 테스트 서버의 소스코드가 보관된다.

- Feature: 각 개발자들이 임의로 자신들의 작업량을 작업한다.

Input validation

본 프로젝트에서는 클라이언트의 요청값을 검증함에 있어 모든 요청의 형태를 DTO 형태로 정의하고 해당 DTO 에 값을 넣기 전에 Joi 라이브러리를 사용하여 요청값에 대한 검증을 수행한다.

tsconfig setting

각 파일에서 다른 파일을 import 함에 있어서 보다 가독성을 높이기 위해 @domain과 같이 태그를 하여 손쉽게 import를 할 수 있습니다.

tsconfig.json 파일의 예

1
2
3
4
5
6
7
8
9
10
11
12
13
{

"compilerOptions": {

"paths": {

"@domain/": ["server/domain/"]

}

}

}

위처럼 옵션을 설정하면 복잡한 filepath 대신 위의 태그네임을 통해 import 할 수 있습니다.

이때 위의 태그네임이 잘 반영이 되지 않는 경우가 있는데, 이는 웹팩에서 트랜스파일링을 하는 과정에서 webpack.config.js 세팅을 바꾸어 줌으로써 해결이 가능합니다.

태그 네이밍을 하기 위해서 tsconfig-paths-webpack-plugin 을 사용하는데 해당 플러그인은 다음과 같이

루트 plugin이 아닌 resolve 내의 plugin 내에 설정되어야 합니다.

webpack.config.js의 예

\

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

{

​ resolve: {

​ plugins: [

new TsconfigPathsPlugin({

​ configFile: './tsconfig.json' // setup tsconfig path

​ })

​ ];

​ }

}

\

Author

frontalnh(Namhoon Lee)

nodejs 에서 sequelize 사용하기

sequelize 에서 객체를 기반으로 데이터 입출력을 하기 위해 model을 정의한다.

설치하기

1
npm install -- save sequelize

Connection 연결하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const Sequelize = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql'|'sqlite'|'postgres'|'mssql',
operatorsAliases: false,

pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},

// SQLite only
// storage: 'path/to/database.sqlite'
}

모델 정의하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const User = sequelize.define('user', {
firstName: {
type: Sequelize.STRING
},
lastName: {
type: Sequelize.STRING
}
});

// force: true will drop the table if it already exists
User.sync({force: true}).then(() => {
// Table created
return User.create({
firstName: 'John',
lastName: 'Hancock'
});
});

query

1
2
3
User.findAll().then(users => {
console.log(users)
})
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×