override end express

Vamos a ver una forma sencilla y elegante de hacer un override del metodo end en Express

Tomaremos de base el ejemplo de uno de los articulos de este blog

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

app.get('/', function (req, res) {
  res.send('Hello World!');
})

var server = app.listen(3000, function () {

  console.log('Server listening at http://%s:%s', server.address().address, server.address().port);

})

Vamos a hacer un ejemplo de como medir el tiempo que tarda una peticion en ser procesada y como podemos añadirlo a nuestra respuesta

Override de end en Express

Nuestro nuevo codigo quedaria de la siguiente manera

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

//Nuestro primer punto de entrada a todas las peticiones
app.use(function (req, res, next) {
    //Guardamos la fecha de la peticion
    var requestTime = new Date();

    //Hacemos una copia de la funcion original end
    var rEnd = res.end;

    //Sobreescribimos la funcion end
    res.end = function (chunk, encoding) {
        //Volvemos a poner la funcion end como estaba
        res.end = rEnd;

        //Fecha de la respuesta
        var responseTime = new Date();
        var duration = responseTime.getTime() - requestTime.getTime();
        
        //Modificamos la respuesta original
        var response = chunk.toString();
        response += " (response in " + duration + "ms)";
        chunk = new Buffer(response);

        //Hay que cambiar el Content-Length de la respuesta o tendremos problemas con el servidor
        res.set('Content-Length', chunk.length);

        //Regeneramos el ETag para evitar cacheo de las respuestas
        var etag;
        var generateETag = app.get('etag fn');
        if (typeof generateETag === 'function') {
            if ((etag = generateETag(chunk, encoding))) {
                res.set('ETag', etag);
            }
        }

        //Fin de la peticion
        return res.end(chunk, encoding);
    };

    next();

});

app.get('/', function (req, res) {

    // Paramos nuestra ejecucion
    // Codigo cogido de la libreria sleep https://github.com/ErikDubbelboer/node-sleep
    var e = new Date().getTime() + (Math.random() * 1000);

    while (new Date().getTime() <= e) {
        ;
    }

    res.send('Hello World!');
});

var server = app.listen(3000, function () {

    console.log('Server listening at http://%s:%s', server.address().address, server.address().port);

});

Si vamos a la url http://localhost:3000 veremos algo similar a:

Hello World! (response in 326ms)

Podeis usar esta funcion para infinidad de cosas: grabar las peticiones que se realicen a vuestro servidor en una base de datos, hacer logging de las peticiones, cambiar la respuesta en funcion de algun parametro, etc…