Dharma

[Express] Node.js 의 웹프레임워크 익스프레스에서의 미들웨어 만들기 본문

프로그래밍

[Express] Node.js 의 웹프레임워크 익스프레스에서의 미들웨어 만들기

광이랑 2013. 2. 21. 18:32
Express (Node.js의 웹 프레임 워크) 에서의 Middleware 개념은 쉽게 설명하자면 Java 에서의 Filter 와 비슷한 개념입니다. 자주 쓰이고 통념적으로 쓰이는 행위들을 미리 걸러주는 역할을 한다고 볼 수 있습니다.  

예로 들면 express 가 내부적으로 쓰고 있는 formidable 은 HTTP의 request 를 정리하는데 탁월합니다. 그러나 개발자가 매번 formidable 을 불러서 정리하는 것이 번거로울 수가 있기 때문에 이를 middleware 로 만들어서 

   app.use(express.bodyParser());


이런식으로 선언만 해두면 사용이 되는 것입니다. (내부적으로 formidable 이 쓰이고 있음. ) 

이런 미들웨어를 만드는 법이 찾아보진 않았지만 예제가 많지는 않습니다. (너무 쉬워서 그럴 수도..)


다행히 위 링크에 가면 fineuploader 가 올리는 xhr 방식의 asynchronous 데이타 전송을 잡아채서 req.files 에 정리하는 부분을 미들웨어로 구현한 소스가 있습니다. 비록 옛날 소스이긴 하지만 (요즘 express 가 너무 많이 발전을 한 관계로..) 어떻게 미들웨어를 만드는지 참조하시면 좋을 듯합니다. 

/*jslint node: true */
"use strict";
var formidable = require('formidable'),
qs = require('qs');
function mime(req) {
var str = req.headers['content-type'] || '';
return str.split(';')[0];
}
/**
* octetStream: mostly nicked from connect's multipart.js
*
* Parse application/octet-stream request bodies,
* providing the parsed object as `req.body`
* and `req.files`.
*
* Configuration:
*
* The options passed are merged with [formidable](https://github.com/felixge/node-formidable)'s
* `IncomingForm` object, allowing you to configure the upload directory,
* size limits, etc. For example if you wish to change the upload dir do the following.
*
* app.use(fineuploaderExpressMiddleware({ uploadDir: path }));
*
* @param {Object} options
* @return {Function}
* @api public
*/
exports = module.exports = function(options){
options = options || {};
return function octetStream(req, res, next) {
if (req._body) return next();
req.body = req.body || {};
req.files = req.files || {};
// ignore GET
if ('GET' == req.method || 'HEAD' == req.method) return next();
// check Content-Type
if ('application/octet-stream' !== mime(req)) return next();
// flag as parsed
req._body = true;
// parse
var form = new formidable.IncomingForm(),
files = {},
done;
Object.keys(options).forEach(function(key){
form[key] = options[key];
});
function ondata(name, val, data){
if (Array.isArray(data[name])) {
data[name].push(val);
} else if (data[name]) {
data[name] = [data[name], val];
} else {
data[name] = val;
}
}
form.on('file', function(name, val){
ondata(name, val, files);
});
form.on('error', function(err){
if (!options.defer) {
err.status = 400;
next(err);
}
done = true;
});
form.on('end', function(){
if (done) return;
try {
req.body = null;
req.files = qs.parse(files);
if (!options.defer) next();
} catch (err) {
form.emit('error', err);
}
});
form.parse(req);
if (options.defer) {
req.form = form;
next();
}
};
};
view raw index.js hosted with ❤ by GitHub


글을 퍼올 수가 없어서 어쩔 수 없이 제 gist 에 올렸습니다. 원문은 위에 링크되어 있는 주소로 가면 나옵니다. (동작하는지에 대한 보장은 해 드릴 수 없습니다) 

(req, res, next) 로 이루어진 전형적인 미들웨어형 함수 선언이 보입니다. 위 사이트를 가면 어떻게 npm 패키지를 만드는 지에 관한 방법도 감을 잡으실 수가 있을 것입니다.