微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

My Node.js应用程序提供WebSockets和RESTful接口.我为Backbone.synch写了一些替代品,用于与Socket.IO一起作为传输.

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

+----------------+---------------------------------+--------------------+
| 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,doc) {
        return err ? cb(err.message,null) : cb(null,doc);
    });
});

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

解决方法

如果你真的想混合这两个函数的逻辑,那么你的客户端代码将参数传递给你的socket.on回调函数的方式将不得不改变.您可以使用当前设置来接近它:

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

   });

}

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

var veryGenericCallback = function(info,action) {

   var query = info.id ? { _id: info.id } : {};

   usermodel.find(query,doc) {

     return err ? action.send(404,null) : action.send(200,doc);

   });

}

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐