Node.js后端框架设计构想(1)(2)
postData拦截器
- mass.define("intercepters/postData","querystring",function(qs){
- console.log("本模块用于取得POST请求过来的数据,并作为request.body而存在");
- return mass.intercepter(function(req,res){
- console.log("进入postData回调");
- reqreq.body = req.body || {};
- if ( req._body || /GET|HEAD/.test(req.method) || 'application/x-www-form-urlencoded' !== req.mime ){
- return true;
- }
- var buf = '';
- req.setEncoding('utf8');
- function buildBuffer(chunk){
- buf += chunk
- }
- req.on('data', buildBuffer);
- req.once('end',function(){
- try {
- if(buf != ""){
- req.body = qs.parse(buf);
- req._body = true;
- }
- req.emit("next_intercepter",req,res)
- } catch (err){
- req.emit("next_intercepter",req,res,err)
- }finally{
- req.removeListener("data",buildBuffer)
- }
- })
- });
- });
query拦截器
- mass.define("intercepters/query","querystring,url",function(qs,URL){
- console.log("本模块用于取得URL的参数并转为一个对象,作为request.query而存在");
- return mass.intercepter(function(req, res){
- req.query = ~req.url.indexOf('?')
- ? qs.parse(URL.parse(req.url).query)
- : {};
- return true;
- })
- })
methodOverride拦截器
- mass.define("intercepters/methodOverride",function(){
- console.log("本模块用于校正method属性");
- var methods = {
- "PUT":"PUT",
- "DELETE":"DELETE"
- },
- method = mass.configs.method || "_method";
- return mass.intercepter(function(req, res){
- reqreq.originalMethod = req.method;
- var defaultMethod = req.method === "HEAD" ? "GET" : req.method;
- var _method = req.body ? req.body[method] : req.headers['x-http-method-override']
- _method = (_method || "").toUpperCase();
- req.method = methods[_method] || defaultMethod;
- if(req.body){
- delete req.body[method];
- }
- return true;
- })
- })
json拦截器
- mass.define("intercepters/json",function(){
- console.log("本模块处理前端发过来的JSON数据");
- return mass.intercepter(function(req, res, err){
- reqreq.body = req.body || {};
- if (req._body || 'GET' == req.method || !~req.mime.indexOf("json")){
- console.log("进入json回调")
- return true;
- }else{
- var buf = '';
- req.setEncoding('utf8');
- function buildBuffer(chunk){
- buf += chunk;
- }
- req.on('data', buildBuffer);
- req.once('end', function(){
- try {
- req.body = JSON.parse(buf);
- req._body = true;
- req.emit("next_intercepter",req,res);
- } catch (err){
- err.status = 400;
- req.emit("next_intercepter",req,res,err);
- }finally{
- req.removeListener("data",buildBuffer);
- }
- });
- }
- })
- })
而在这么多拦截器中,最重要的是matcher拦截器,它进入框架MVC系统的入口。把原始请求的pathname取出来,然后通过正则匹配它,只要一个符合就停下来,然后加载对应的控制器文件,调用相应的action处理请求!
- mass.define("intercepters/matcher","url",function(URL){
- console.log("用于匹配请求过来的回调")
- return mass.intercepter(function(req,res){
- console.log("进入matcher回调");
- var pathname = URL.parse(req.url).pathname, is404 = true,method = req.method, arr = mapper[method];
- for(var i =0, obj; obj = arr[i++];){
- if(obj.matcher.test(pathname)){
- is404 = false
- var url = mass.adjustPath("app/controllers/",obj.namespace, obj.controller+"_controller.js")
- mass.require(obj.controller+"_controller("+url +")",function(object){
- object[obj.action](req,res);//进入控制器的action!!!
- console.log(obj.action)
- },function(){
- var err = new Error;
- err.statusCode = 404
- req.emit("next_intercepter",req,res,err);
- })
- break;
- }
- }
- if(is404){
- var err = new Error;
- err.statusCode = 404
- req.emit("next_intercepter",req,res,err);
- }
- })
- })
最后殿后的是handle404拦截器:
- mass.define("intercepters/handle404","fs,path",function(fs){
- console.log("本模块用于处理404错误");
- return function(req, res, err){
- console.log("进入handle404回调");
- var accept = req.headers.accept || '';
- if (~accept.indexOf('html')) {
- res.writeHead(404, {
- "Content-Type": "text/html"
- });
- var html = fs.readFileSync(mass.adjustPath("public/404.html"))
- res.write((html+"").replace("{{url}}",req.url));
- res.end();
- } else if (~accept.indexOf('json')) {//json
- var error = {
- message: err.message,
- stack: err.stack
- };
- for (var prop in err) error[prop] = err[prop];
- var json = JSON.stringify({
- error: error
- });
- res.setHeader('Content-Type', 'application/json');
- res.end(json);
- // plain text
- } else {
- res.writeHead(res.statusCode, {
- 'Content-Type': 'text/plain'
- });
- res.end(err.stack);
- }
- }
- })
再回过头来看控制器部分,从模板中生成的controller非常简单:
- mass.define("comments_controller",function(){
- return {
- "index":function(){},
- "create":function(){},
- "new":function(){},
- "edit":function(){},
- "destroy":function(){},
- "update":function(){},
- "show":function(){}
- }
- });
因此你需要动手改到其可用,如
- "show":function(req,res){
- res.writeHead(200, {
- "Content-Type": "text/html"
- });
- var html = fs.readFileSync(mass.adjustPath("app/views/tests/show.html"))
- res.write(html);
- res.end();
- }
以后会判定action的结果自动调用视图。
当然现在框架还很简单,只用了半天时间而已。它必须支持ORM与静态文件缓存才行。此外还有cookie,session等支持,这些做成一个拦截器就行了。
总结如下:
◆ 判定网站是否存在,没有通过手脚架构建一个
◆ 读取routes等配置文件,生成MVC系统所需要的控制器,视图与模型。
◆ 通过热部署功能,监视用户对配置文件的修改,进一步智能生成需要控制器,视图与模型。
◆ 通过一系列拦截器处理请来,直到matcher拦截器里面进入MVC系统,这时通过模型操作数据库,渲染页面。拦截器群集的应用大大提高应用的伸缩性。现在还没有来得及得node.js的多线程,可能这里面能发掘出许多好东西呢。
原文:http://www.cnblogs.com/rubylouvre/archive/2011/12/13/2286280.html






