How do I overload the functionality of app.listen in expressjs

I've been trying to create (basically) a factory function that configures and builds an expressjs server for a dozen smaller specialized servers I have. For part of this I want to augment the listen function.

I would like to know the best way to go about this. I'm also looking for a reusable design choice here.

Server is created normally:

var httpServer = express();
    ...

Because of the way express is designed (Not sure if I am correct) I cannot access a {whatever}.prototype.listen. So I have come up with two approaches.

Using an additional variable in the current scope:

 var oldListen = httpServer.listen;
 httpServer.listen = function(callback){
    ...
    oldListen.call(httpServer, options.port, options.host, function(){
       ...
       if ( typeof callback == 'function' ) callback();                    
    });
 };

Which works and is fairly straight forward but then I have a variable hoisting wart. I also have a closure solution, but I think it may be too obtuse to be practical:

httpServer.listen = (function(superListen){
   return function(callback){
      ...
      superListen.call(httpServer, options.port, options.host, function(){
         ...               
         if ( typeof callback == 'function' ) callback();
      });
   };                                             
})(httpServer.listen);

Both examples are part of the factory context and I am intentionally reducing the arguments passed to the function.

Any help would be appreciated.

If you insist on "overloading", make sure you implement the original footprint (such is the nature of overloading). Express listen is just an alias to node's internal http listen method:

server.listen(port, [host], [backlog], [callback]);

UPDATE: Express even suggests using node's server API for custom implementations: http://expressjs.com/4x/api.html#app.listen

Otherwise, you should create your own custom listen method which would be defined like:

httpServer.myCustomListen = function (callback) {
    httpServer.listen.call(httpServer, options.port, options.host, callback);
}

The second option is your best bet, but in order for it to work, you must extend the express library. Express is open source and hosted on Github. Fork it and modify it as you please. Periodically pull in new updates so you stay up-to-date with the core library. I do this all the time with node modules.

There are two benefits from doing it this way:

  1. You have complete control to customize the code however you see fit while staying up to date with the code written by the original authors.

  2. If you find a bug or build a cool feature, you can submit a pull request to benefit the community at large.

You would first fork the repository, then grab the URL for your fork, clone it, and then add a reference to the original "upstream" repo:

git clone [url_to your_fork]
cd express
git remote add upstream git@github.com:strongloop/express.git

Then you can push changes to your own repo (git push). If you want to get updates from the original repo, you can pull from the upstream repo: git pull upstream master.

If you want to add your custom fork of express as an npm module for a project, you would use the following:

npm install git://github.com/[your_user_name]/express.git --save

As Victor's answer pointed out, express's prototype is in express/lib/application.js. That file is used to build express and is exported via the application namespace in express/lib/express.js. Therefore, the .listen function can be referenced using express.appliction.listen.

One can use this method then: (similar to Victor's method)

var express = require('express');

express.application._listen = express.application.listen;
express.application.listen = function(callback) {
  return this._listen(options.port, options.host, callback);
};

One can also use Lo-dash's _.wrap function if you don't want to store the base function in a variable yourself. It would look something like this:

var express = require('express');
var _ = require('lodash');

express.application.listen = _.wrap(express.application.listen, function(listenFn) {
  return listenFn(options.port, options.host, callback); // Called with the same this
};

However, using these methods would run into the problems that you mentioned in your question (variable hoisting, creating an extra variable). To solve this, I would usually create my own subclass of express.application and replace the .listen function in that subclass and tell express to use that subclass instead. Due to express's current structure, however, you cannot replace express.application with your own subclass without overriding the express() function itself.

Hence, what I would do is to take over express.application.listen completely since it is only 2 lines. It is rather simple!

var express = require('express');
var http = require('http');

express.application.listen = function(callback) {
  return http.createServer(this).listen(options.port, options.host, callback);
};

You can even make an https option!

var express = require('express');
var http = require('http');
var https = require('https');

express.application.listen = function(callback) {
  return (options.https ? http.createServer(this) : https.createServer({ ... }, this))
          .listen(options.port, options.host, callback);
};

Note: One of the other answers mentions forking express and modifying it. I would have a tough time justifying that for such a small function.

You should be able to easily overload the express listen function. You can access it in the following Object path: express.application.listen

So, you can implement something like this:

var express = require('express');

express.application.baseListen = express.application.listen;
express.application.listen = function(port) {
console.log('Port is: ' + port);
  this.baseListen(port);
};

The implementation of the listen function is in the following path under the express module folder: node_modules\express\lib\application.js

Bind and listen for connections on the given host and port. This method is identical to node's http.Server#listen().

var express = require('express');
var app = express();
app.listen(3000);

The app returned by express() is in fact a JavaScript Function, designed to be passed to node's HTTP servers as a callback to handle requests. This allows you to provide both HTTP and HTTPS versions of your app with the same codebase easily, as the app does not inherit from these (it is simply a callback):

var express = require('express');
var https = require('https');
var http = require('http');
var app = express();

http.createServer(app).listen(80);
https.createServer(options, app).listen(443);

The app.listen() method is a convenience method for the following (if you wish to use HTTPS or provide both, use the technique above):

app.listen = function(){
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};

Reference:http://expressjs.com/api.html

Hope This helps.