app.js 파일에 DB 연동을 위한 스키마, 모델 그리고 라우터 등이 한꺼번에 있어서 모듈화를 한다.
사실 아직 익숙해지지 않아서 모듈화한 부분들이 어떤 흐름을 가지고 실행되는지 정확히는 모른다... 계속 공부해야함..
database----bookmark_schema.js //DB 스키마 설정
|----database_loader.js //config.js에 있는 값들을 바탕으로 몽고DB 연결, 스키마, 모델 생성
public-------404.html //에러 페이지
|------bookmark.html //메인 페이지,,,
routes-------bookmark.js //라우팅 경로에 맞는 함수 호출되게 함수 작성
|------route_loader.js //config.js에 있는 라우터 설정 정보로 라우터 초기화
app.js //메인 파일
config.js //설정 파일
....
bookmark_schema.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | var Schema={}; Schema.createSchema=function(mongoose){ console.log('createSchema 호출됨'); var BookmarkSchema=mongoose.Schema({ bmurl:{type:String,required:true}, bmname:{type:String}, bmimage:{type:String} }); console.log('bookmark schema 정의함'); return BookmarkSchema; } module.exports=Schema; | cs |
database_loader.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 | var mongoose=require('mongoose'); var database={}; database.init=function(app,config){ console.log('init 호출됨'); connect(app,config); }; function connect(app,config){ console.log('connect 호출됨'); mongoose.Promise=global.Promise; mongoose.connect(config.db_url,{useNewUrlParser:true}); database.db=mongoose.connection; database.db.on('error',console.error.bind(console,'mongoose connection error')); database.db.on('open',function(){ console.log('db에 연결됨:'+config.db_url); createSchema(app,config); }); database.db.on('disconnected',function(){ console.log('연결이 끊어짐 5초후 재 연결'); setInterval(connectDB,5000); }); //app.set('database',database); } function createSchema(app,config){ var confLen=config.db_schemas.length; console.log('설정의 DB 스키마 수:'+confLen); for(var i=0;i<confLen;i++){ var curItem=config.db_schemas[i]; var curSchema=require(curItem.file).createSchema(mongoose); console.log('%s 모듈을 이용해 스키마 생성함.',curItem.file); var curModel=mongoose.model(curItem.collection,curSchema); console.log('%s 컬렉션을 위해 모델 정의함.',curItem.collection); database[curItem.schemaName]=curSchema; database[curItem.modelName]=curModel; console.log('스키마 [%s], 모델 [%s] 생성됨',curItem.schemaName, curItem.modelName); } app.set('database',database);//모듈 불러서 init하면 app 안에 database가 들어감 } module.exports=database; | cs |
bookmark.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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | var path=require('path'); var addBookmark=function(database,bmurl,bmname,bmimage,callback){ console.log('addBookmark 호출됨: '+bmurl+', '+bmname+', '+bmimage); var bm=new database.BookmarkModel({"bmurl":bmurl,"bmname":bmname,"bmimage":bmimage}); bm.save(function(err){ if(err){ callback(err,null); return; } console.log('사이트 추가함'); callback(null,bm); }); }; var siteViewer=function(database,callback){ console.log('siteViewer 호출됨'); database.BookmarkModel.find({},function(err,results){ if(err){ callback(err,null); return; } //console.log('즐겨찾기 검색 결과: '); //console.dir(results); if(results.length>0){ console.log('즐겨찾기 찾음'); callback(null,results); }else{ console.log('즐겨찾기 못찾음'); callback(null,null); } }); }; var images=function(req, res) { console.log('/process/bookmark 호출됨.'); //config.js의 설정과 route_loader에 의해 실행됨 var database=req.app.get('database'); try{ var paramUrl=req.body.bookmarkUrl; //html 파일에서 입력된 input 값들 var paramName=req.body.bookmarkName; var file=req.files; //요청된 파일 var imgpath=file[0].path; //업로드할 이미지 경로 console.log('file정보: '); console.log(file); console.log(imgpath); //console.dir('파일 정보: '+req.file[0]); console.log('요청 파라미터들:'+paramUrl+', '+paramName); if(database){ addBookmark(database,paramUrl,paramName,imgpath,function(err,result){ if(err) throw err; if(result){ console.dir(result); res.writeHead('200',{'Content-Type':'text/html;charset=utf8'}); res.write('<h2>사이트 추가 성공</h2>'); res.write('<a href="/public/bookmark.html">즐겨찾기 추가 페이지로 돌아가기</a>'); res.end(); }else{ res.writeHead('200',{'Content-Type':'text/html;charset=utf8'}); res.write('<h2>사이트 추가 실패</h2>'); console.dir(result); res.end(); } }); }else{ res.writeHead('200',{'Content-Type':'text/html;charset=utf8'}); res.write('<h2>db 연결 실패</h2>'); res.end(); } }catch(err) { console.dir(err.stack); } }; var viewer=function(req,res){ var database=req.app.get('database'); console.log('즐겨찾기 보기, siteViewer() 호출'); if(database){ siteViewer(database,function(err,results){//즐겨찾기 찾으면 callback으로 results받아옴 res.writeHead('200',{'Content-Type':'text/html;charset=utf8'}); res.write('<h1>나의 즐겨찾기 보기</h1>'); res.write('<table border=1><tr><th>즐겨찾기</th><th>이미지</th></tr>'); for(var i=0;i<results.length;i++){ res.write('<tr>'); res.write('<td><a href="'+results[i].bmurl+'">'+results[i].bmname+'</a></td>'+ '<td><img width="80" height="80" src="../'+results[i].bmimage+'"/></td>'); res.write('</tr>'); console.log('이미지: ',results[i].bmimage); } res.write('</table>'); res.end(); }); } }; module.exports.images=images; module.exports.viewer=viewer; | cs |
route_loader.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 | var route_loader={}; //route_loader 객체 생성 var config=require('../config'); //config 모듈 참조 // 파일 업로드용 미들웨어 var multer = require('multer'); //multipart/form-data를 다루기 위한 미들웨어, 주로 파일 업로딩에 쓰임, 다른 양식은 처리 안함 var fs = require('fs'); var static=require('serve-static'); var path=require('path'); //multer 미들웨어 사용 : 미들웨어 사용 순서 중요 body-parser -> multer -> router // 파일 제한 : 10개, 1G var storage = multer.diskStorage({ //storage 엔진은 파일을 디스크에 저장하는 걸 제어함 destination: function (req, file, callback) { callback(null, 'uploads') //목적지:uploads 폴더에 파일 생김 }, filename: function (req, file, callback) { callback(null, file.originalname) //파일명 } }); var upload = multer({ //옵션들 storage: storage, //파일이 저장될 장소 limits: { //업로드될 데이터의 제한 files: 10, //파일 수? fileSize: 1024 * 1024 * 1024 //파일 용량 1GB } }); route_loader.init=function(app,router){ //router_loader 초기화 함수, 메인에서 app객체와 router객체 넘겨줌 console.log('route_loader.init 호출됨'); initRoutes(app,router); app.use('/uploads', static(path.join(__dirname, 'uploads'))); //정적 파일 제공, 디렉토리 uploads에 있는 파일 제공, localhost://uploads/... } function initRoutes(app,router){ //사용자가 요청한 라우터 경로에 따라 함수 호출 console.log('initRoutes 호출됨'); var routeLen=config.route_info.length; //라우터 정보의 개수 for(var i=0;i<routeLen;i++){ var curItem=config.route_info[i]; //i번째 라우터 정보 var curModule=require(curItem.file); //i번째 라우터 정보의 파일 정보 if(curItem.type=='get'){ //i번째 라우터 정보의 타입이 get이면 router.route(curItem.path).get(curModule[curItem.method]); //라우팅 경로와 해당 경로로 요청이 왔을 때의 함수 이름 지정 }else if(curItem.type=='post'){ if(curItem.method=='images'){ //이미지 저장하는 함수인 경우 router.route(curItem.path).post(upload.array('bookmarkImg',1),curModule[curItem.method]); }else{ router.route(curItem.path).post(curModule[curItem.method]); } }else{ console.error('라우팅 함수 타입 알 수 없음'+curItem.type); } } app.use('/',router); // 루트에 router 마운트 } module.exports=route_loader; | cs |
app.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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | /* 기능 추가 : routes폴더에 파일 생성 후 함수 추가 -> config.js의 route_info에 객체 추가 */ // Express 기본 모듈 불러오기 var express = require('express') , http = require('http') , path = require('path'); // Express의 미들웨어 불러오기 var bodyParser = require('body-parser') , cookieParser = require('cookie-parser') , static = require('serve-static') , errorHandler = require('errorhandler'); // 에러 핸들러 모듈 사용 var expressErrorHandler = require('express-error-handler'); // Session 미들웨어 불러오기 var expressSession = require('express-session'); //클라이언트에서 ajax로 요청 시 CORS(다중 서버 접속) 지원 var cors = require('cors'); // 익스프레스 객체 생성 var app = express(); var config=require('./config'); console.log('config.server_port->'+config.server_port); var database_loader=require('./database/database_loader'); var route_loader=require('./routes/route_loader'); // 기본 속성 설정 app.set('port', config.server_port); // body-parser를 이용해 application/x-www-form-urlencoded 파싱 app.use(bodyParser.urlencoded({ extended: false })) // body-parser를 이용해 application/json 파싱 app.use(bodyParser.json()) // public 폴더와 uploads 폴더 오픈 app.use('/public', static(path.join(__dirname, 'public'))); app.use('/uploads', static(path.join(__dirname, 'uploads'))); // cookie-parser 설정 app.use(cookieParser()); // 세션 설정 app.use(expressSession({ secret:'my key', resave:true, saveUninitialized:true })); //클라이언트에서 ajax로 요청 시 CORS(다중 서버 접속) 지원 app.use(cors()); route_loader.init(app,express.Router()); //app, 라우터 모듈 전달 // 404 에러 페이지 처리 var errorHandler = expressErrorHandler({ static: { '404': './public/404.html' } }); app.use( expressErrorHandler.httpError(404) ); app.use( errorHandler ); // Express 서버 시작 http.createServer(app).listen(app.get('port'), function(){ console.log('Express server listening on port ' + app.get('port')); database_loader.init(app,config);//database_loader파일에서 한번에 로딩, 스키마는 config 파일에 }); | cs |
config.js
1 2 3 4 5 6 7 8 9 10 11 | module.exports={ server_port:3000, db_url:'mongodb://localhost:27017/local', db_schemas:[ {file:'./bookmark_schema',collection:'bookmark0',schemaName:'BookmarkSchema',modelName:'BookmarkModel'} ], route_info:[ {file:'./bookmark',path:'/process/bookmark',method:'images',type:'post'}, {file:'./bookmark',path:'/process/siteview',method:'viewer',type:'post'} ] }; | cs |
출처 Do it Node.js + 직접 수정