WebSockets plus RESTful interface, how to write DRY code in Node.js?

My Node.js application provides both WebSockets and RESTful interfaces . I wrote a small replacement for Backbone.synchfor use with Socket.IO as a transport.

Problem with DRY : client callbacks contain almost the same logic as callbacks for RESTul paths. An example of matching events and data emitted by the client, and the corresponding action:

+----------------+---------------------------------+--------------------+
| 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    |
+----------------+---------------------------------+--------------------+

Example (99% duplicated logic / code):

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

Since I have been playing with Node.JS and programming events (and JavaScript) for several days, I am looking for good advice on how to design a “controller” as a general purpose object that can handle duplicate code easily. Thank.

+5
1

, , 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, 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" , send , :

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

   });

}

, , - ( , - ). , , , Request/Response, . , , , , .

+1

All Articles