2017-02-17 114 views
1

我正在学习nodejs/expressjs并将其锁定到Spring MVC模式,因为我想我可以保留我的文件的粘性。但它不太工作了,因为我所期望的......expressjs - 无法处理请求

server.js

const express = require('express'); 
const bodyParser= require('body-parser'); 
const MongoClient = require('mongodb').MongoClient; 
const app = express(); 

var PeopleController = require('./controller/PeopleController.js') 
var db; 

app.all('/*', function(req, res, next) { 
    var path = req.url; 
    var controller; 

    switch (true) { 
    case /\/people.*/g.test(path): 
     controller = new PeopleController(); 
     console.log("people"); 
     controller.process(req, res, next); 
     break; 
    case /\/foo.*/g.test(path): 
     console.log("foo"); 
     break 
    default: 
     console.log("nada"); 
     break; 
    } 
}); 

PeopleController.js

const express = require('express'); 
const bodyParser= require('body-parser'); 
const MongoClient = require('mongodb').MongoClient; 
const app = express(); 

var PeopleController = function PeopleController() {} 

PeopleController.prototype.process = function (req, res, next) { 
    var baseURL = '/people'; 

    console.log('path is ' + req.path); 

    app.use(bodyParser.urlencoded({extended: true})); 
    app.set('view engine', 'ejs'); 

    app.get(baseURL, (req, res) => { 
    console.log('people get'); 
    }); 

    app.post(baseURL, (req, res) => { 
    console.log('people post'); 
    }); 
}; 

module.exports = PeopleController; 

后来,当我做一个GET ON /人/我得到的以下控制台了...

people 
path is /people/ 

我希望app.get运行并得到以下的输出:

people 
path is /people/ 
people get 
+0

从我所看到的你可以创建一个'app'的新实例,但它不会侦听任何端口。 'app.get'将匹配请求到它正在监听的端口。 – char

回答

1

Lurk我强烈推荐使用express.router像这样:

PeopleController.js 

const express = require('express'); 
const router = express.Router(); 

// then apply middleware 
router.use(...); 

// then define your endpoints 
router.get('/', (req, res) => { 
    console.log('get PeopleController.js root'); 
} 

module.exports = router; 

在server.js

... 
const PeopleController = require('./controller/PeopleController.js'); 

// apply PeopleController to '/people' route 
app.use('/people', PeopleController); 

所以,现在当你请求GET /人,你应该看到节点的console.log。这种方法最大的好处是它可以让你的代码保持清洁(无需根据路由切换,你可以让快速处理宁静的行为)

+0

我觉得我比其他方法更喜欢这种方法。你可以将这个路由器/控制器概念应用于'app.method',而不仅仅是中间件? – char

+0

嗨char,不知道我在理解你的问题。这里的模式是对终点进行分组,例如假设PeopleController具有GET/sayHello和POST/reproduce并且AnimalController具有GET/makeNoise和POST /后代终结点。你可以用app.use('/ people',PeopleController)和app.use('/ animal',AnimalController)'附加'它们。最后用POST /动物/后代消耗它们。如果您问的是按方法对端点进行分组(例如,一个文件中的所有GET调用),那么这是我不熟悉的一种不同模式。 – Kunal

+0

这是一个干净的解决方案。谢谢。 – Lurk21

2

发生这种情况是因为您只有一个Express监听端口实例。

在server.js:

const express = require('express'); 
const bodyParser= require('body-parser'); 
const MongoClient = require('mongodb').MongoClient; 
const app = express(); // we create an instance of Express 
... 
app.listen(process.ENV.PORT); //this specific instance listening on port 

当你过去的app在server.js

const app = express(); 
... 
controller = new PeopleController(app); 

和进口在PeopleController.js创造把PeopleController的新实例,你必须

const express = require('express'); // delete this 
const app = express(); // delete this 

//add this: 
var PeopleController = function PeopleController(appInstance) { 
    this.app = appInstance; 
} 

PeopleController.prototype.process = function (req, res, next) { 
    var baseURL = '/people'; 
    var app = this.app; 

    console.log('path is ' + req.path); 

    app.use(bodyParser.urlencoded({extended: true})); 
    app.set('view engine', 'ejs'); 

    app.get(baseURL, (req, res) => { 
    console.log('people get'); 
    }); 

    app.post(baseURL, (req, res) => { 
    console.log('people post'); 
    }); 
};