使用NodeJS作为HTTP服务器 – 如何避免spagetti?

我想使用nodejs作为我正在处理的项目的光Web服务器。 我主要是一个PHP程序员,所以我这样做的方式是不同于我习惯的。

在这个应用程序中,我使用angular度来请求一些数据。 我想将其格式设置为“/ get / some_data”。 在我的节点端,我使用连接并静态指向我的http目录。

现在,当我提出一些数据请求时,人们推荐的唯一方法就是查找请求并将其传回。 这比我习惯于每个文件处理请求的文件结构要less得多。

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语句?

除了Jim所说的之外,我还会添加一些可以使代码更清晰的模式。

在不同的function中validation路线参数

如果你使用带参数的路线,比如说app.get('/blog/:slug', ...那么你可以使用app.param来validation给定的slug存在,并执行必要的动作(发送404或如果你的数据库中没有slug or slug或者加载由给定的slug identified子标识的博客文章,将你的请求传递给另一个路由)

  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标识的post,就不需要检查你的请求处理程序 – 非常干净的方法。

将请求处理函数拆分为中间件函数

你也可以把你的请求处理函数分解成几个更小的函数,然后按顺序调用它们(实际上express会为你调用它们)。 比方说,你build立一个讨论论坛,你有这样的路线:

 app.get('/forum/:fid/thread/:tid', function(){ // ... }) 

你需要在一个函数中处理论坛和线程加载 – 很快你就会看到spaghetti代码(特别是这两个操作将被asynchronous执行)。 为了解决这个问题 ,你可以把这些function分成独立的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 。 您可以使用尽可能多的中间件function,以保持您的代码清晰。

我希望这会有所帮助。

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'] }) 

或者,您可以使用像docs显示的正则expression式:

 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); }); 

但是,是的,你应该分别申报每个动词。