일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
26 | 27 | 28 | 29 | 30 | 31 |
- 알고리즘
- 장고 프로젝트 순서
- 예술영화추천
- 독립영화플랫폼
- JavaScript
- Django Blog
- Node.js
- 장고
- Exercism
- ART_Cinema
- 자바스크립트
- 장고 프로젝트
- 파이썬 웹프로그래밍 장고
- Django
- passport.js
- til
- Algorithm
- 타사인증
- python
- mongodb
- 북마크앱
- Blog
- Bookmark
- join()
- MYSQL
- 북마크만들기
- MyPick31
- 개발
- 프로젝트
- 장고 개발 순서
- Today
- Total
Juni_Dev_log
(node.js) [Part.7] 익스프레스 프로젝트를 모듈화하기 - 설정 파일 만들기 본문
웹 서버 안의 각 기능을 별도의 파일로 분리하여 모듈로 만들면, 수정이 필요할 때 웹 서버의 메인 파일을 수정하지 않고 모델 부분만 수정해도 된다. 또 새로운 모듈을 추가할 때도 메인 파일을 수정하지 않아도 되기 때문에 서버의 유지관리에 용이하다.
그런데 새로운 모듈을 추가했을 때, 메인 파일을 수정하지 않고도 어떤 모듈이 추가되었는지 어떻게 알 수 있을까?
설정 파일을 만들고 메인 파일이 설정 파일을 불러오도록 하면 된다. 왜냐하면 새로운 모듈을 추가했을 때, 설정 파일만 수정해도 메인 파일에서 변경된 내용을 알 수 있기 때문이다.
즉, 설정 파일의 이름이 config.js 라면 이 파일을 모듈 파일로 만들고 이 파일 안에 설정 정보를 넣어 둔 후 서버가 실행될 때 메인 파일에서 이 설정 파일에 있는 설정 정보를 읽어 들이도록 만들면된다.
config.js 파일 안에 들어 있는 설정 정보에는 ① 서버를 실행하는 데 필요한 정보 ② 데이터베이스 정보 등을 담아둔다.
① 서버 정보는 서버를 실행할 때 필요한 포트 등의 정보를 말하는 것이다. 환경 변수로 설정하여 읽어들일 수 있으며, config.js 파일에 넣어둘 수 있다.
② 데이터베이스 정보는 데이터베이스 연결에 필요한 URL이나 인증 정보를 말한다. mongoose를 사용하는 데이터베이스는 스키마를 생성한 후에 데이터베이스에 접근하기 때문에, 스키마 생성 부분을 별도 파일로 분리해두고 스키마 파일의 로딩 정보를 config.js 파일에 넣어둘 수 있다.
설정 파일 분리하기
(설정 정보를 이용하여 최종 모듈 구조 만들기)
[config.js] [app2.js]
- server_port => app.set('port', config.server_port)
[./database/database.js]
- db_url => database.init(app, config) init = function(app, config){
- db_schemas (스키마 정보) => database.init(app, config) => connect = function(...){
createSchema = function(...){ ↘
[./database/user_schema.js]
[./routes/route_loader.js]
- route_info (라우팅 정보) => route_loader.init(app, express.Router()); => init = function(app){ (라우팅 초기화)
↘
[./routes/user.js]
config.js 파일 안에는 서버를 실행할 때 필요한 포트 정보와 데이터베이스 연결에 필요한 데이터베이스 URL 정보를 넣어둔다.
데이터베이스 연결에 필요한 데이터베이스 스키마 정보는 db_schemas 배열 객체에 넣어둔다. 그리고 사용자가 요청한 패스 정보로 익스프레스에서 라우팅하던 정보는 route_info 배열 객체에 넣어둔다.
app.js 파일을 복사해서 app2.js 를 만들고 설정정보를 만들어서 app2.js 로 불러들여보자.
config.js 를 만들고 포트정보와 데이터베이스 URL 정보를 코드로 입력한다.
#Config.js
1
2
3
4
|
module.exports = {
server_port : 3000,
db_url :'mongodb://localhost:27017/local',
}
|
cs |
- config.js 파일에 server_port와 db_url을 작성했다.
#app2.js
1
2
3
4
5
6
7
8
9
|
...
// config.js 모듈 분리
var config = require('./config');
...
// 기본 속성 설정 (config.js)
app.set('port', process.env.PORT || config.server_port);
|
cs |
- 분리한 설정파일인 config.js 를 require() 한다.
- 설정파일에 있는 포트번호가 들어가는 부분을 config.server_port로 변경한다.
설정 파일에 데이터베이스 스키마 정보 넣기
데이터베이스 스키마 정보를 설정하여 사용하는 방법을 알아보자. 먼저, config.js 파일 안의 db_schemas 배열 객체에 들어가는 정보는 다음과 같다.
#config.js
1
2
3
4
5
6
7
8
9
10
11
12
|
module.exports = {
server_port : 3000,
db_url :'mongodb://localhost:27017/local',
...
db_schemas : [
{file:'./user_schema', collection:'user3', schemaName:'UserSchema', modelName:'UserModel'}
]
...
}
|
cs |
db_schemas 속성의 값은 배열이며, 배열의 각 원소는 스키마 파일의 정보가 된다.
(스키마 파일을 정의할 때 사용하는 속성)
속성 이름 | 설명 |
file | 스키마 파일을 지정한다. |
collection | 데이터베이스의 컬렉션 이름을 지정한다. |
schemaName | 스키마 파일을 불러들인 후, 반환된 객체를 어떤 속성으로 할 것인지 지정한다. |
modelName | 스키마에서 모델 객체를 만든 후, 어떤 속성 이름으로 할 것인지 지정한다. |
데이터베이스에 들어가는 스키마 정보를 별도 파일에 넣어 두었으니 그 파일에서 사용자 관련 스키마를 로딩해야한다.
그런데, 새로운 스키마를 추가하면 로딩 작업을 위한 코드도 변경해야하기 때문에 로딩작업에 필요한 파일을 또 다시 분리하는 것이 좋다. [database] 폴더 안에 database.js 를 만들고 코드를 작성한다.
#databse.js
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
// 데이터 베이스 로딩작업에 필요한 파일
// 수정할 부분들이 많은 것은 해당 폴더로 옮겨놓음.
var mongoose = require('mongoose');
//database 객체에 db, schema, model 모두 추가
var database = {};
// init()메소드를 호출하면 데이터베이스와 연결된다.
database.init = function(req,res){
console.log('init() 호출됨.');
connect(app,config);
}
// 데이터베이스에 연결하고 응답 객체의 속성으로 db 객체 추가
function connect(app,config){
console.log('connect() 호출됨.');
// 데이터베이스 연결 : config의 설정 사용
mongoose.Promise = global.Promise; // mongoose의 Promise 객체는 global의 Promise 객체 사용하도록 한다.
mongoose.connect(config.db_url);
database.db = mongoose.connection;
database.db.on('error', console.error.bind(console, 'mongoose connection error.'));
database.db.on('open', function(){
console.log('데이터베이스에 연결되었습니다. : ' + config.db_url);
// config에 등록된 스키마 및 모델 객체 생성
createSchema(app,config);
});
database.db.on('disconnected', connect);
}
// config에 정의된 스키마 및 모델 객체 생성
function createSchema(app, config){
var schemaLen = config.db_schemas.length;
console.log('설정에 정의된 스키마의 수 : %d', schemaLen);
for(var i=0; i<schemaLen; i++){
var curItem = config.db_schemas[i];
// 모듈 파일에서 모듈 불러온 후 createSchema() 함수 호출하기
var curSchema = require(curItem,file).createSchema(mongoose);
console.log('%s 모듈을 불러들인 후 스키마 정의함.', curItem.file);
var curModel = mogoose.model(curItem.collection, curSchema);
console.log('%s 컬렉션을 위해 모델 정의함.', curItem.collection);
database[curItem.schemaName] = curSchema;
database[curItem.modelName] = curModel;
console.log('스키마 이름 [%s], 모델 이름 [%s] 이 database 객체의 속성으로 추가됨.', curItem.schemaName, curItem.modelName);
}
app.set('database', database);
console.log('database 객체가 app 객체의 속성으로 추가됨.')
}
//database 객체를 module.exports에 할당
module.exports = database;
|
cs |
- database.js 파일 안에서는 자바스크립트 객체를 하나 만들어 database 변수에 할당한다.
- 이 객체는 다시 module.exports에 지정되어 이 모듈 파일을 불러들이는 쪽에서 사용할 수 있다. 이 객체에 추가되어있는 메서드는 init() / connect() / createSchema() 세 개이다.
- init() 메소드는 단순히 connect() 메소드를 호출하는데 connect() 메소드 안에 들어가는 코드는 앞에서 데이터베이스에 연결하는데 사용하는 코드이다.
- createSchema() 메소드는 config.js 파일의 db_schemas 속성에 들어있는 스키마 정보로 스키마를 만든다. 다만, 직접 스키마를 만드는 것이 아니라, 각 용도별로 데이터베이스 스키마를 정의한 모듈 파일을 다시 로딩한다.
예를 들어) 사용자 정보를 저장하기 위해 정의한 스키마는 [database]폴더의 user_schema.js파일에서 만드는데, database.js 파일에서는 user_schema.js 파일을 로딩하여 실행하는 역할만 한다.
- config.js 파일에 넣어둔 스키마 파일 데이터를 사용해 각각의 스키마를 담고 있는 모듈 파일을 로딩한 후, 스키마와 모델 객체를 database 객체의 속성으로 추가한다.
이렇게 하면, config.js 파일에서 지정한 스키마 이름과 모델 이름이 database 객체의 속성이름이 된다.
databse 객체에 속성들을 모두 추가했다면, app 객체의 set() 메소드를 호출하여 database 라는 속성이름으로 추가한다.
이렇게 하면, 사용자가 요청했을 때 이 함수로 라우팅되어 실행되며, req.app.get('database') 코드로 database 객체를 참조할 수 있다.
user_schema.js 파일의 내용은 앞에서 사용자 정보를 저장하려고 만든 스키마와 같다.
이제 user_schema.js 파일에 넣어준 코드를 살펴보자.
#user_schema.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
//////////////////
//스키마 파일 분리//
//////////////////
var crypto = require('crypto');
var Schema = {};
Schema.createSchema = function(mongoose) {
...
console.log('UserSchema 정의함.');
return UserSchema;
};
// module.exports에 UserSchema 객체 직접 할당
module.exports = Schema;
|
cs |
- Schema 자바스크립트 객체를 만들고, createSchema라는 속성 이름으로 함수를 추가한다.
- 함수의 마지막 부분에서 return 으로 UserSchema를 반환한다.
이제 데이터베이스와 관련된 모든 기능을 파일에서 분리했으므로, 하나의 파일로 되어있던 코드가 설정 파일인 config.js 파일과 [database] 폴더 안에 들어있는 파일들로 나뉘었다.
이제부터는 데이터베이스 관련 기능을 추가하고싶을때, [database]폴더 안에 필요한 파일을 만들고 config.js 파일의 db_schema 속성에 정보를 추가하면된다.
만약, 스키마를 새로 만들고 싶다면 어떻게 해야할까? 데이터 베이스 스키마를 새로 정의하려면 다음 두 단계를 거치면된다.
① 스키마 정의 파일을 추가한다. 만약, 사용자 정보를 추가하고 싶다면 먼저 사용자 스키마를 user_schema.js 파일에 정의한다.
② 새로 만든 스키마 정보를 config.js 설정 파일 안에 추가한다. 1단계에서 사용자 스키마를 만들었다면 이 스키마 정보를 config.js 파일 안에 들어 있는 db_schemas 배열 객체 안에 추가한다. 이렇게 하면 해당 정보가 추가되어 어떤 스키마를 만들었는지 알 수 있다.
(데이터베이스 스키마를 새로 정의하는 작업 과정)
[config.js] [./database/board_schema.js]
db_schemas (스키마 정보) (스키마 정의)
-> file : './user_schema' ↑
-> collection : 'users3' 1단계 : 스키마 정의 파일 추가
-> schemasName : 'UserSchema'
-> modelName : 'UserModel' ↖
2단계 : 설정 정보 추가
설정 파일에 라우팅 정보 넣기
데이터베이스 기능을 별도의 파일로 분리하고 해당 정보를 config.js 파일에 추가하듯이 라우팅 함수도 모듈로 분리한 후, 설정 정보에 추가할 수 있다. 사용자를 조회하거나 추가하는 기능을 라우팅하는 코드는 원래 메인 파일에 있었지만, 이제 이 코드는 [routes] 폴더 안에 만든 user.js 파일에 들어있다.
라우팅 정보를 config.js 파일에 등록해두면 별도의 모듈 파일에 분리되어 있는 사용자 기능들을 사용자 요청으로 라우팅하여 사용할 수 있다.
#config.js
1
2
3
4
5
6
7
8
9
|
module.exports = {
...
route_info : [
{file : './user', path : '/process/login', method : 'login', type : 'post'}
, {file : './user', path : '/process/adduser', method : 'adduser', type : 'post'}
, {file : './user', path : '/process/listuser', method : 'listuser', type : 'post'}
]
}
|
cs |
이렇게 설정한 정보를 [routes] 폴더 안의 route_loader 파일에서 읽은 후 [routes] 폴더 안에 있는 라우팅 관련 모듈 파일을 읽어 들인다.
각 속성의 이름과 설명은 다음과 같다.
속성 이름 | 설명 |
file | 라우팅 파일을 지정한다. |
path | 클라이언트로부터 받은 요청 패스를 지정한다. |
method | 라우팅 파일 안에 만들어 놓은 객체의 함수 이름을 지정한다. |
type | get 이나 post와 같은 요청 방식을 지정한다. |
[routes] 폴더의 router_loader.js 파일은 어떤 라우팅 모듈들이 있는지 확인한 후, 해당 모듈 파일들을 읽어서 실행한다.
따라서 메인 파일 app2.js에서는 단순히 route_loader.js 모듈에 정의된 init() 함수를 호출하기만 하면 된다.
1
2
3
4
5
6
7
8
9
10
|
...
// 모듈로 분리한 라우팅 파일 불러오기
var route_loader = require('./routes/route_loader');
...
// 라우팅 정보를 읽어들여 라우팅 설정
route_loader.init(app, express.Router());
...
});
|
cs |
이제 app2.js 파일에는 사용자의 요청을 처리하는 코드는 하나도 남아있지 않다.
라우팅 함수를 추가할 때 두 단계를 거친다.
① 라우팅 코드가 들어 있는 모듈 파일을 추가한다. 만약, 사용자 기능을 추가하고 싶다면, [routes]폴더 안에 user.js 파일을 추가하고 그 안에 사용자 정보 저장이나 조회 기능을 만들어준다.
② 새로 만든 라우팅 모듈의 정보를 config.js 설정 파일 안에서 추가한다. route_info 배열 객체 안에 정보를 추가하면 된다.
app2.js 파일을 실행한 후, 웹 브라우저에서 로그인, 사용자 추가, 사용자 리스트 기능을 다시 테스트한다.
config.js 파일로 설정 정보를 잘 분리했다면 실행 결과는 똑같을 것이다.
'Theorem (정리) > node.js' 카테고리의 다른 글
(node.js) [Part.8] 뷰 템플릿 적용하기 - ejs 뷰 템플릿 사용하기 (0) | 2021.01.30 |
---|---|
(node.js) [Part.7] 익스프레스 프로젝트를 모듈화하기 - UI 라이브러리로 웹 문서를 예쁘게 꾸미기 (semantic UI) (0) | 2021.01.28 |
(node.js) [Part.7] 익스프레스 프로젝트를 모듈화하기 - 사용자 정보 관련 기능을 모듈화하기 (0) | 2021.01.23 |
(node.js) [Part.7] 익스프레스 프로젝트를 모듈화하기 - 모듈화 방법 자세히 살펴보기 (0) | 2021.01.21 |
(node.js) [Part.6] 데이터 베이스 사용하기 - MySQL 데이터베이스 사용하기 (0) | 2020.12.27 |