我想使用nodejs作为我正在开发的项目的轻量级网络服务器。我主要是一名 PHP 程序员,所以我的做法与我习惯的不同。
在此应用程序中,我使用 Angular 来请求一些数据。我想将其格式化为“/get/some_data”。在我的节点端,我使用 connect 并将其静态指向我的 http 目录。
现在,当我请求一些数据时,人们似乎唯一推荐的就是查找该请求并将其传回。这比文件结构的组织性要差得多,就像我习惯的每个文件处理请求的地方一样。
var connect = require("connect");
var app = connect();
app.use(connect.static("/my_http_dir"));
app.use(function(req, res)
{
if(req.originalUrl == "foo")
{
// do something relating to foo
}
else if(req.originalUrl == "bar")
{
// do something relating to bar
}
else
{
// do nothing
}
});
connect.createServer(app).listen(80);
那么用什么来组织这个呢?我是否需要创建一个获取处理程序、放置处理程序、删除处理程序、发布处理程序等,并将“文件”传递给 switch 语句?
express.js 内置了一个非常强大的路由引擎。您应该查看 应用程序路由文档 并熟悉它。
要回答您的问题,您可以这样做:
app.get('/foo', function(req,res){
// foo
})
app.get('/bar', function(req,res){
// bar
})
或者,您可以使用参数值
app.get('/api/:action', function(req,res){
// action can be foo, bar, whatever...
// access action from req.params['action']
})
或者,您可以使用正则表达式,如文档所示:
app.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function(req, res){
var from = req.params[0];
var to = req.params[1] || 'HEAD';
res.send('commit range ' + from + '..' + to);
});
但是,是的,您应该单独声明每个动词。
除了 Jim 所说的之外,我还会添加另一种模式,可以使您的代码更简洁。
如果您使用带有参数的路由,例如
app.get('/blog/:slug', ...
,那么您可以使用 app.param
来验证给定的 slug
是否存在并执行必要的操作(发送 404
或将您的请求传递给另一个如果您的数据库中没有该 slug
,则路由或加载由给定 slug
标识的博客文章),例如
function slugParam (req, res, next, slug) {
Post.findBySlug({ slug: slug }, function (err, post) {
if (err) return res.send(500, 'SERVER ERROR');
if (!post) return res.send(404);
res.locals.post = post; // you will be able to access 'post' in your template
next();
})
}
当您设置应用程序时,您必须调用 app.param 例如
app.param('slug', slugParam);
使用这种方法,如果存在给定的 slug 标识的帖子,则无需检查请求处理程序 - 非常干净的方法。
您还可以将请求处理函数拆分为几个更小的(更干净的)函数并按顺序调用它们(实际上express会为您调用它们)。比方说,您建立了一个讨论论坛,并且您有这样的路线:
app.get('/forum/:fid/thread/:tid', function(){
// ...
})
您需要在单个函数中处理论坛和线程加载 - 很快您就会看到意大利面条式代码(特别是这两个操作都将异步执行)。为了修复它,您可以将该功能拆分为独立的功能,负责一个功能,例如加载论坛、加载线程等。 示例:
function loadFormum (req, res, next) {
Forum.load(/* params here */, function (err, forum) {
if (err) return res.send(500);
if (!forum) return res.send(404);
res.locals.forum = forum;
next();
})
}
function loadThread (req, res, next) {
// you can use forum from res.locals.forum here
Forum.findThread(/* params here */, function (err, thread) {
if (err) return res.send(500);
if (!thread) return res.send(404);
res.locals.thread = thread;
next();
})
}
app.get('/forum/:fid/thread/:tid', loadFormum, loadThread, function(){
// cleaner code
})
或者
var forumMiddleware = [loadForum, loadThread]
app.get('/forum/:fid/thread/:tid', forumMiddleware, function(){
// cleaner code
})
使用这种方法,函数可能会相互依赖,即
loadForum
加载模型,然后由
loadThread
使用。您可以使用任意数量的中间件函数,以保持代码清晰。我希望这会有所帮助。