MVC 모델

api 서버를 구축하기 위해 mvc 모델을 구축해보았다.
db는 mongodb를 이용하였고 연동시켜 보았다.

routes에서 요청을 받고 controllers로 요청을 하는 그림을 보고 https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/routes 링크를 참조하며 공부한 결과 아래와 같은 mvc 패턴을 구현하였다.

app.js

var express = require('express');
var http = require('http');
var bodyParser = require('body-parser');
 
var app = express();
 
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
 
app.listen(8888);
 
console.log("Server is Running...");
 
var catalog = require('./api/routes/catalog');
 
app.use('/', catalog);
 

userController.js

(function() {
  'use strict';
})();
 
var User = require('../models/userModel.js');
 
exports.get_dummy = function (req, res) {
  res.end('get_dummy');
};
 
exports.put_dummy = function (req, res) {
  res.end('put_dummy');
};
 
exports.post_dummy = function (req, res) {
  var userIns = User();
  userIns.name = 'jung';
  res.end(userIns.name);
};
 
exports.delete_dummy = function (req, res) {
  res.end('delete_dummy');
};

catalog.js(route)

catalog.js 에서 각 controllers를 추가하여 라우팅을 해준다.

(function() {
  'use strict';
})();
 
var express = require('express');
var router = express.Router();
 
var userController = require('../controllers/userController');
 
router.get('/', function (req, res) {
  res.redirect('user router');
});
 
//user router
router.get('/user', userController.get_dummy);
router.post('/user', userController.post_dummy);
router.put('/user', userController.put_dummy);
router.delete('/user', userController.delete_dummy);
 
 
module.exports = router;

userModel.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
 
mongoose.createConnection('mongodb://localhost:27017/test');
 
var UserSchema = new Schema({
    name: String,
    address: String,
    phone: String,
    email: String
});
 
module.exports = mongoose.model('User', UserSchema);


'Framework > Nodejs' 카테고리의 다른 글

node js, mongodb 연동 with mongoose  (0) 2017.08.16
이메일 발송  (0) 2017.07.13
mocha  (0) 2017.07.05
미들웨어(1):cookieParser, bodyParser, limit, query  (0) 2017.04.05
connect  (0) 2017.04.04

mocha

mocha는 Javascript Testing Tool이다.

Installation

$ npm install mocha --global

테스트 코드는 .spec.js로 관리하여 -w를 추가하여 실행하여 파일 변경시 자동으로 테스트 러너가 실행된다

$ mocha

test

describe()으로 테스트 suite을 만들고 그 안에 it()으로 테스트 코드를 작성한다. descirbe()은 중첩해서 사용할 수 있다.

Asynchronous

it()에 사용하는 함수에 파라미터로 done을 전달하면 자동으로 비동기 테스트로 인식하고 비동기 로직이 완료된 시점에서 파라미터로 받은 done()을 실행해 주면 테스트가 완료된다. assertion은 done()을 실행하기 전에 작성하면 됩니다. done()을 실행하지 않으면 기본 타임아웃인 2000ms후에 타임아웃 실패로 간주합니다.

done() 이라는 콜백 함수를 비동기 코드가 정상적으로 완료되었을 때 호출하면 된다. done()이 호출되지 않는다면 설정된 기본 timeout 시간으로 2ms 후에 실패로 간주된다.

before(function(){
  console.log('before');
});
 
it('test spec', function(done){
  // do the test
  console.log(1);
  done();
});
 
after(function(){
  console.log('after');
});

mocha --timeout 3000 처럼 timeout 값을 변경할 수 있다.

Hooks

테스트 케이스의 상황에 따라 실행되어야 하는 부분을 설정할 때 사용

describe('Hooks example', function() {
  before(function() {
    // 테스터들을 실행하기 전에 한번 실행하는 부분
    console.log('before');
  });
 
  after(function() {
    // 테스터들을 모두 실행하고 나서 한번 실행하는 부분
    console.log('after');
  });
 
  beforeEach(function() {
    // 각 테스터들이 실행되기 전에 실행하는 부분
    console.log('beforeEach');
  });
 
  afterEach(function() {
    // 각 테스터들이 실행된 후에 실행하는 부분
    console.log('afterEach');
  });
 
  // test case
  it('test1', function() {
    // write test logic
    console.log('1');
  });
 
  it('test2', function() {
    // write test logic
    console.log('2');
  });
});
 

결과 화면

Hooks example
before
beforeEach
1
    ✓ test1
afterEach
beforeEach
2
    ✓ test2
afterEach
after
 
 
  2 passing (8ms)


'Framework > Nodejs' 카테고리의 다른 글

이메일 발송  (0) 2017.07.13
MVC model  (0) 2017.07.07
미들웨어(1):cookieParser, bodyParser, limit, query  (0) 2017.04.05
connect  (0) 2017.04.04
FileUpload  (0) 2017.03.26

쿠키와 요청본문, 쿼리 스트링을 해석하는 미들웨어

cookieParser()

웹 브라우저의 쿠키를 해석해 req.cookies에 넣는다.

var express = require('express');
var cookieParser = require('cookie-parser');
 
var app = express();
app.use(cookieParser());
 
app.get('/', function (req, res) {
  // Cookies that have not been signed
  console.log('Cookies: ', req.cookies);
 
  // Cookies that have been signed
  console.log('Signed Cookies: ', req.signedCookies);
})
 
app.listen(3000, function(req, res) {
  console.log("running on 3000 port");
});

cookie response setting

res.setHeader('Set-Cookie', 'foo=bar');
res.setHeader('Set-Cookie', 'tobi=feert');
res.end();

req.signedCookies(서명된 쿠키)

//req.signedCookies에 {name : value} 추가
res.cookie('name', 'value', {signed:true});
 
//req.cookies에 {name : value} 추가
res.cookie('name', 'value', {signed:false});

bodyParser()

요청 본문을 받아서 해석해 req.body에 넣는다.

var express = require('express')
var bodyParser = require('body-parser')
 
var app = express()
 
// create application/json parser
var jsonParser = bodyParser.json()
 
// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false })

bodyParser.urlencodeed :
url 인코딩된 본문만을 parse하는 미들웨어를 반환, x-www-form-urlencoded parser 임을 명시
기본값은 true이지만 더이상 사용되지 않는다.

app.use(bodyParser.urlencoded({ extended: false }))

top-level middleware(모든 요청에 body 구문을 parse한다)

var express = require('express')
var bodyParser = require('body-parser')
 
var app = express()
 
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
 
// parse application/json
app.use(bodyParser.json())
 
app.use(function (req, res) {
  res.setHeader('Content-Type', 'text/plain')
  res.write('you posted:\n')
  res.end(JSON.stringify(req.body, null, 2))
})
 
app.listen(3000);

express4.x부터 body-parser 미들웨어의 multipart 기능 불가능해짐
connect-multipart 등 미들웨어 사용

limit()

bodyParser()와 같이 사용해서 요청이 커지지 않게 제한한다.

예시를 위해 bodyPaser 미들웨어에 multipart(업로드 및 form-data파싱)을 추가하가 위해 connect-multiparty 미들웨어를 사용

var fs = require('fs');
var express = require('express');
var multiparty = require('connect-multiparty');
var multipartMiddleware = multiparty();
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
 
var app = express();
 
app.use(cookieParser());
app.use(bodyParser.json({limit: '1mb'}));
//업로드하여 저장할 디렉토리 지정(디렉토리가 존재하여야 한다.)
app.use(multiparty({uploadDir : __dirname + '/multipart'}));
 
app.get('/', function(req, res) {
  fs.readFile('index.html', function(err, data) {
    res.send(data.toString());
  })
});
 
app.post('/', function(req, res) {
  console.log(req.body);
  console.log(req.files);
 
  res.redirect('/');
});
 
app.listen(3000, function() {
  console.log('server running on 3000 port');
})

limit가 필요한 이유 :
악의적인 사용자가 HTTP 클라이언트를 사용해 대량의 파일 데이터를 만들어서 공격하는 것을 방지

var express = require('express');
var http = require('http');
var app = express();
 
var req = http.request({
  method: 'POST',
  port:3000,
  headers: {
    'Content-Type': 'application/json'
  }
});
 
req.write('[');
var n = 30000000;
while(n--) {
  req.write('"foo",');
}
req.write('"bar"]');
 
req.end();

query()

요청 URL 쿼리 스트링을 req.query에 넣는다.

app.use(function (req, res) {
  res.setHeader('Content-Type', 'text/plain')
  res.write('you posted:\n')
  res.end(JSON.stringify(req.query));
})

localhost:3000?query=query_data 로 url 호출시 {"query":"query_data"}가 출력된다.

'Framework > Nodejs' 카테고리의 다른 글

이메일 발송  (0) 2017.07.13
MVC model  (0) 2017.07.07
mocha  (0) 2017.07.05
connect  (0) 2017.04.04
FileUpload  (0) 2017.03.26

커넥트

노드는 기본적으로 HTTP 모듈을 가지고 있고, Connect는 HTTP 모듈에 여러 플러그인을 추가할 수 있는 미들웨어 프레임워크이다. Express는 Connect를 내장하고 있는 웹 프레임워크이다.

  • 커넥트 애플리케이션 준비

    var connect = require('connect');
    var app = connect();
    app.listen(3000);
  • 커넥트 미들웨어 동작방식
    커넥트에서 미들웨어 컴포넌트는 req, res, next() 세 인자를 가진다.

    function logger(req, res, next) {
      consloe.log('%s %s', req.method, req.url);
      next();
    }

    next()를 실행해 디스패처에 제어를 넘겨준다.

    var connect = require('connect');
    var app = connect();
    app.use(logger);
    app.listen(3000);
  • 미들웨어 순서의 중요성

    function logger(req, res, next) {
      consloe.log('%s %s', req.method, req.url);
      next();
    }
    function hello(req, res) {
      res.setHeader('Content-Type', 'text/plain');
      res.end('hello world');
    }
    connect().use(logger).use(hello).listen(3000);

    미들웨어 순서는 인증과 같은 경우에 사용하면 좋다

    connect()
      .use(looger)
      .use(restrictFileAccess)
      .use(serveStaticFiles)
      .use(hello)

'Framework > Nodejs' 카테고리의 다른 글

이메일 발송  (0) 2017.07.13
MVC model  (0) 2017.07.07
mocha  (0) 2017.07.05
미들웨어(1):cookieParser, bodyParser, limit, query  (0) 2017.04.05
FileUpload  (0) 2017.03.26

FileUpload

body-parser는 파일을 업로드하는 경우에 json과 urlencoded 양식 제출만 처리한다. multi-part를 처리하기 위해서 connect-busboy 모듈을 사용하였다.

주의해야 할 점은 이미지를 저장하고자 하는 폴더가 경로에 있어야한다.

var express = require('express');
var fs = require('fs');
// var bodyParser = require('body-parser');
var busboy = require('connect-busboy');
var app = express();
 
// app.use(bodyParser.urlencoded({extended: false}));
app.use(busboy());
 
app.listen(3303, function() {
  console.log("Server Start");
});
 
app.get('/', function(req, res) {
  fs.readFile('index.html', function(err, data) {
    res.writeHead(200, { 'Content-Type': 'text/html'});
    res.end(data, function(error) {
      console.log(error);
    })
  })
})
 
app.post('/upload', function(req, res) {
  var fstream;
  req.pipe(req.busboy);
  req.busboy.on('file', function(fieldname, file, filename) {
    console.log("Uploading: " + filename);
    fstream = fs.createWriteStream(__dirname + '/files/' + filename);
    file.pipe(fstream);
    fstream.on('close', function() {
      res.redirect('back');
    });
  });
});


'Framework > Nodejs' 카테고리의 다른 글

이메일 발송  (0) 2017.07.13
MVC model  (0) 2017.07.07
mocha  (0) 2017.07.05
미들웨어(1):cookieParser, bodyParser, limit, query  (0) 2017.04.05
connect  (0) 2017.04.04

+ Recent posts