Lets say I have multiple places where I call response.send(someData)
. Now I want to create a single global interceptor where I catch all .send
methods and make some changes to someData
. Is there any way in express.js? (hooks, listeners, interceptors, ...)?
6 Answers
You can define a middleware as below (taken and modified from this answer)
function modifyResponseBody(req, res, next) {
var oldSend = res.send;
res.send = function(data){
// arguments[0] (or `data`) contains the response body
arguments[0] = "modified : " + arguments[0];
oldSend.apply(res, arguments);
}
next();
}
app.use(modifyResponseBody);
-
I tried the above and it does work. However res.send is being invoked twice for all HTTP methods (POST, PUT, DELETE) and is invoked only once for GET. Any idea why res.send is being invoked twice? – KBJ Dec 28 '16 at 16:33
-
3res.send=oldSend adding the above line before invoking the oldSend method fixes the above mentioned problem. Thanks! – KBJ Jan 03 '17 at 19:54
-
Thanks @Jugz, an explanation into how that fixes the issue would be great, thanks. – Aukhan Jul 06 '17 at 15:14
-
1for this you have to look at [internal implementation](https://github.com/expressjs/express/blob/master/lib/response.js#L158). res.send in the flow is being invoked again internally. So after initial monkey patching this method, just before you invoke it you patch it back to original implementation. Else this leads to calling your interceptor twice. Anyways monkey patching is not always a good idea and more over the above solution is a crude way. Better to go with the below answer of using express-interceptor – KBJ Jul 10 '17 at 04:18
-
is it possible to utilized statusCode in user-defined send function? Status code will be set using res.status(500) in the controller. – leopragi Jan 29 '19 at 06:27
-
Hello there! I'm a little confused... Doing that, will I lost the original res behavior (res.write, res.send, res.end ...)? Would this be avoided by applying oldSend.apply(res, arguments)? Thank you very much. – Rogério Oliveira Jul 08 '19 at 19:04
for those finding on google, based off the top answer:
app.use((req, res, next) => {
const oldSend = res.send
res.send = function(data) {
console.log(data) // do something with the data
res.send = oldSend // set function back to avoid the 'double-send'
return res.send(data) // just call as normal with data
}
next()
})

- 421
- 4
- 12
-
1This one is working as it should. I'm using res.json which I have override using your example, and add data that I want to send in every response. Great job – bumerang Apr 08 '20 at 10:07
-
1Thanks it worked for me! The line res.send = oldSend is importnat. – Zaki Mohammed Jul 14 '20 at 13:35
Yes this is possible. There are two ways to do this, one is to use a library that provides the interception, with the ability to run it based on a specific condition: https://www.npmjs.com/package/express-interceptor
The other option is to just create your own middleware (for express) as follows:
function modify(req, res, next){
res.body = "this is the modified/new response";
next();
}
express.use(modify);

- 6,632
- 3
- 26
- 34
-
I am trying to create a middleware for the `response` in order to set custom headers if `statusCode` is `200` but if I run `console.log(res.statusCode)` in the middleware function I always get `200` even if the status code is `404` `401` `500`. Is there another method to get the right status code for the response? – Sabbin May 23 '19 at 15:11
-
middleware is called before you send the response. It just chek whether user can acces some routes, or no. But you can use it for some other stuff. But it wont be executed after it reach the rout especially after sending response – bumerang Apr 08 '20 at 08:25
For my case, I had to use a middleware with typicode/json-server
and be able to get a different response object than just a blunt javascript array.
While the typicode/json-server
response was something like:
[
{
...
}
]
After applying the middleware:
module.exports = (req, res, next) => {
const oldSend = res.send;
res.send = (data) => {
const oldData = JSON.parse(data);
// we want to change the response only if a blunt array is sent
// also, we do this for the old sake of not sending json arrays
if(Object.prototype.toString.call(oldData) === '[object Array]') {
data = {
data: oldData
};
}
res.send = oldSend;
return res.send(data);
};
next();
}
The response looks as follows:
{
data: [
{
...
}
]
}

- 383
- 7
- 8
Just want to provide a practical usage example with intercepting res.json
.
When we're writing express server, we might send the status
and message
in every response according to the situation like below.
app.post('/test', (req, res) => {
res.json({status: 1, message: "some_error", otherData: "nothing"})
})
But, what if I don't want to write the status and message in every time? I could add new function to build a template response body to send the data when using res.json
.
const messageMap = {
0: "success",
1: "some_error"
}
app.use((req, res, next) => {
const originJson = res.json
res.json = (status, jsonData) => {
const fixedResponse = {
status,
message: messageMap[status]
}
originJson.call(res, {...jsonData, ...fixedResponse})
}
next()
})
Then I just need to use below function.
app.get("/test", (req, res) => {
res.json(1, {otherData: 1})
})
You can even use builder pattern to do this.
app.use((req, res) => {
res.buildFixedResponse = function (status) {
const fixedResponse = {
status,
message: messageMap[status]
}
res.json = function (jsonData) {
originJson.call(this, {...jsonData, ...fixedResponse})
}
return this
}
})
Then trigger function like below.
app.get("/test", (req, res) => {
res.buildFixedResponse(1).json({otherData: 1})
})

- 2,190
- 1
- 8
- 14
You can simply do it using NODEJS and Express, say you are calling an API and want to send modify the data before sending response back.
router.get('/id', (req,res) => {
... //your code here filling DATA
let testData = {
"C1": "Data1",
"C2": "Data2",
"yourdata": DATA
};
res.send(testData);
});

- 4,571
- 2
- 13
- 27

- 295
- 4
- 4