Intercept response body in NodeJS express app

April 4, 2016
by Rahil Shaikh

Intercept response body or transform response body in express which, ever way you call it, one thing is for sure its not as straight forward as it is for the request body object. In this tutorial we will write an express middleware to intercept the response body object of an API request.

You may have written many express apps but it is quite possible, you may have never required the need to intercept the response body object. Of-course until now.

There may be rare occasions when you would want to do this. For eg. I came across this scenario when I was working on a client project and I decided to Log the API details along with the response body on every request.

I achieved this for my app using this small npm package called express-mung. express-mung exposes the response object in an express middleware, just like we do for a req object. express-mung works by monkey patching the original res.json and res.end methods. Lets have a look a how it works with an example.

Lets first have a simple express app with two get APIs for the demo.
Install the below npm packages.
npm install --save express
npm install --save winston

Folder Structure
/
    index.js
    controllers/
        api.js
    package.json
    node_modules/
index.js
var express = require('express');
var app = express();
var winston = require('winston');

app.use(require('./controllers/api'));

app.listen('3000', function () {
    console.log('listening on port 3000');
});

Adding two routes to controllers/api.js

controllers/api.js
var express = require('express');
var router = express.Router();

router.get('/api1', function(req, res){
    res.json({
        errorCode:0,
        message: 'Hola! I\'m API one'
    });
});

router.get('/api2', function(req, res){
    res.json({
        errorCode:0,
        message: 'Marhabaan! Me API two man'
    });
});

module.exports = router;

To run the app fire up your terminal and run node index.js. You should be able to access our APIs in the browser in the below two paths.
http://localhost:3000/api1
http://localhost:3000/api2

This is our package.json

package.json
{
  "name": "intercept-response-express",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "npm test"
  },
  "author": "Rahil Shaikh <a href="&#109;a&#105;l&#116;o&#x3a;r&#x61;&#104;&#x69;&#108;&#x73;&#107;&#x34;&#55;&#x40;&#103;&#x6d;&#97;&#x69;&#108;&#x2e;&#99;&#x6f;&#109;">r&#x61;&#104;&#x69;&#108;&#x73;&#107;&#x34;&#55;&#x40;&#103;&#x6d;&#97;&#x69;&#108;&#x2e;&#99;&#x6f;&#109;</a> (http://www.ciphertrick.com)",
  "license": "MIT",
  "dependencies": {
    "express": "4.13.4",
    "express-mung": "0.4.2",
    "morgan": "1.7.0",
    "winston": "2.2.0"
  }
}

express-mung

Lets see how we can use express-mung in our application.
Install it and save it to package.json

npm install express-mung --save
Then in your app require the package and create a middleware as shown below.

Usage

usage
var express = require('express');
var app = express();
var mung = require('express-mung');

//middleware to access response body object
app.use(mung.json(
    function transform(body, req, res) {
        // do something with body
        return body;
    }
));

app.use(require('./controllers/api'));

app.listen('3000', function () {
    console.log('listening on port 3000');
});

Note this middle-ware should be placed before the routes for which you want to intercept the response body.

Examples

Modify response body in express

A typical use-case would be adding some common information to API response body or may be deleting some sensitive information from the response body or headers. Building on our demo express app lets add the middle-ware as follows

index.js
var express = require('express');
var app = express();
var winston = require('winston');
var mung = require('express-mung');
// mung middleware
app.use(mung.json(
    function transform(body, req, res) {
//adds mungMessage to every API response
        body.mungMessage = "I intercepted you!";
        return body;
    }
));
app.use(require('./controllers/api'));
app.listen('3000', function () {
    console.log('listening on port 3000');
});

 

Logging response body in express

Another use-case would be to log API response body, for debugging or other purpose. By using the below middleware you can log response body for all APIs by writing the logic at one place instead of having to write separate logs in all routers.
We are using winston logger for our example.

index.js
var express = require('express');
var app = express();
var winston = require('winston');
var mung = require('express-mung');
app.use(mung.json(
    function transform(body, req, res) {
        winston.log('info', {Message:'API REQUEST RESPONSE LOG',  responseBody:JSON.stringify(body)});
        body.mungMessage = "I intercepted you!";
        return body;
    }
));
app.use(require('./controllers/api'));
app.listen('3000', function () {
    console.log('listening on port 3000');
});

Now start the server and hit http://localhost:3000/api1 or http://localhost:3000/api2 you should see the response body getting logged in the console.

SOURCE CODE

Conclusion

This was a short tutorial that provides a mechanism for writing an express middleware to access the response body object. Hope you found it useful. express-mung also provides function to transom response header, you can explore more options on this documentation.

About

Engineer. Blogger. Thinker. Loves programming and working with emerging tech. We can also talk on Football, Gaming, World Politics, Monetary Systems.

Free PDF

Subscribe and get AngularJS Tips PDF. We never spam!
First Name:
Email:

1 comment

  1. Victor
    |

    thx, good article

Leave a Comment