WebSockets加RESTful接口,如何编写Node.js中的DRY代码?

我的Node.js应用程序提供了WebSockets和RESTful接口。 我写了一个替代Backbone.synch与Socket.IO一起使用的传输。

DRY问题 :在客户端事件上执行的callback包含与RESTulpath的callback几乎相同的逻辑。 客户端发出的事件和数据之间的映射示例以及相应的操作:

 +----------------+---------------------------------+--------------------+ | event emitted | data emitted | RESTful URL | +----------------+---------------------------------+--------------------+ | read:users | empty string | GET /users | | read:users | id of the model | GET /users/:id | | create:users | full model as JSON | POST /users | | destroy:users | id of the model | DELETE /users/:id | | update:users | full model as JSON (with id) | PUT /users/:id | | patch:users | partial model as JSON (with id) | PUT /users/:id | +----------------+---------------------------------+--------------------+ 

示例(重复逻辑/代码的99%):

 var UserModel = require('./models/user'); // Mongoose model // Express path app.get('/users/:id?', function (req, res)) { var query = !id ? {} : { _id: id }; UserModel.find(query, function (err, doc) { return err ? res.send(404, null) : res.send(200, doc); }); }; // SocketIO listening to the read:users event socket.on('read:users', function(id, cb) { var query = !id ? {} : { _id: id } UserModel.find(query, function (err, doc) { return err ? cb(err.message, null) : cb(null, doc); }); }); 

因为我在玩Node.JS和事件编程(和JavaScript)几天,所以我正在寻找一个很好的build议,如何devise一个“控制器”,就像一个通用的对象,可以轻松地处理重复的代码。 谢谢。

如果你真的想混合这两个函数的逻辑,那么你的客户端代码将parameter passing给你的socket.oncallback函数的方式将不得不被改变。 你可以用这样的方式来设置它:

 var veryGenericCallback = function(p1, p2) { // Note: Not sure what to name the arguments because they are wildly different // in your two different cases. var query = typeof p1 === "object" : {} : { _id: p1 }; UserModel.find(query, function (err, doc) { var result; if (typeof p2 === "function") { return err ? p2(err.message, null) : p2(null, doc); } else { return err ? p2.send(404, null) : p2.send(200, dox); } }); } 

但是正如你所看到的,在某些时候,你仍然需要重复你试图避免的逻辑。 但是,如果发送事件的socket客户端代码在第一个参数上具有“id”属性的对象中传递,并且为第二个parameter passing了具有send函数的对象,则可以将其减less为:

 var veryGenericCallback = function(info, action) { var query = info.id ? { _id: info.id } : {}; UserModel.find(query, function (err, doc) { return err ? action.send(404, null) : action.send(200, doc); }); } 

然而,在这种情况下,您将需要更改服务器端的代码,以处理您的伪发送方法所做的任何操作(并且您需要首先在客户端有权访问的地方定义该代码)。 这也严重限制了你可以在你的callback中做什么,因为任何你想在实际的Request / Response对象上调用的函数都必须在你的套接字客户端代码中被模仿。 在我看来,这混淆了你的代码的可读性和可扩展性,但是它肯定是可以实现的。