1

I am checking the express.js code and am trying to rewrite it just to learn how to create middlewares (framework). But all the inheritance around the code is confusing me.

Relevant codes:

On the express.js this code:

app.request = { __proto__: req, app: app };
app.response = { __proto__: res, app: app };

keeping in-mind __proto__ is deprecated. @Bergi told me that I can replace such code with:

app.request = Object.create(req);
app.request.app = app;
app.response = Object.create(res);
app.response.app = app;

But now oddly the application.js again has similar code - i think.

// inherit protos
this.on('mount', function(parent){
  this.request.__proto__ = parent.request;
  this.response.__proto__ = parent.response;
  this.engines.__proto__ = parent.engines;
  this.settings.__proto__ = parent.settings;
});

Which is emitted here:

mount_app.mountpath = mount_path;
mount_app.parent = this;

// restore .app property on req and res
router.use(mount_path, function mounted_app(req, res, next) {
  var orig = req.app;
  mount_app.handle(req, res, function(err) {
    req.__proto__ = orig.request;
    res.__proto__ = orig.response;
    next(err);
  });
});

// mounted an app
mount_app.emit('mount', this);

And then even the request.js and response.js have inheritance, seems understandable, though I don't completely understand how they are doing it.

//is this exporting http.IncomingMessage.prototype???
var req = exports = module.exports = {
  __proto__: http.IncomingMessage.prototype
};

I am not very good with javascript. I would like find books to read on the topic of inheritance.

My questions:

  • What is the point of all this inheritance.
  • Isn't the 1st and 2nd case I pointed out redundant?
  • And how should I rewrite avoiding deprecated __proto__?

Background

I am actually just trying to write a simple middleware based system. Something I can do:

// route
app.use('/', function(req,res) {

});

Just that simple, but I also want to add more methods to req and res. That is why I am looking at how connect and express implemented it. Though connect didn't add additional methods to req and res. That's why I am trying to understand express.

A hakish way of adding methods to res or req is:

// middleware
app.use(function(req, res) {
   req.mymethod = function()...
});

Now the next middleware has the additional req method but I find this dirty. That is why I am trying to understand expressjs and how they implemented that inheritance.

Note: I successfully wrote a working simple middleware system but still don't know how to add methods to req/res. I'm also looking into object wrapping (maybe that is what they did to the req and res?)

Community
  • 1
  • 1
majidarif
  • 18,694
  • 16
  • 88
  • 133

1 Answers1

-1

There's nothing inherently wrong with this approach:

app.use(function(req, res) {
    req.mymethod = function()...
});

The middleware runs in the order it's defined, so as long as that appears before your other middleware and routes, you have assurance that it'll be there.

Personally, if it was a static function that wasn't doing anything fancy, I'd store it in a separate module, require() it where I need it, and leave it at that. But if, for some reason, you need request-specific variables in there, it might be handy to do it as you suggested. For example, creating a closure:

app.use(function(req, res, next) {
    // Keep a reference to `someVar` in a closure
    req.makeMessage = (function(someVar) {
        return function () {
            res.json({hello : someVar});
        };
    })(/* put the var here */);

    next();
});

app.get('/hello', function(req, res) {
    req.makeMessage();
});

A contrived, rather useless example, but it could be useful in some cases.

smitelli
  • 6,835
  • 3
  • 31
  • 53