With every middleware, Express passes a res
and a req
objects. These objects extend the native ones that come from http.ServerResponse
and http.ClientRequest
respectively. I'd like to know if it's possible to override or extend methods of the response object.
For example, instead of res.render('home', jsonData);
, I'd like to extend res
with a custom method called customRender and use it like so: res.customRender()
.
I'm not stuck at a particular problem or anything. I'd just like to learn how to extend native objects or, as with this case, object that come from 3rd party modules in Node.js
The best idea would be to add a custom method to the prototype of the response object:
var express = require("express");
express.response.customRender = function() {
// your stuff goes here
};
And this function should be accessible by every res
object.
You can read the source code to see how they extend native objects. Basically they are doing prototype chaining:
express/lib/response.js
var res = module.exports = {
__proto__: http.ServerResponse.prototype
};
And this object becomes a prototype of newely created response object (which comes from connect framework):
res.__proto__ = app.response;
(app.response
is just an alias to res
defined above). Note that __proto__
property is a reference to the prototype of an object.
Be warned though. First of all __proto__
is not a part of EcmaScript (it might not be available in other JavaScript implementations). Secondly: normally you would do inheritance with Object.create
(setting __proto__
directly on an object is a monkey patching and it is generally a bad practice, it may break many things). Read more about that here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain
Just add a middleware that adds the customRender function to res.
function(req, res, next) {
res.customRender = function() {
// implement your custom renderer
}
next();
}
As freakish answered, you can add a method to the prototype. However, it won't have access to other members of the created object.
If you want to have that access, you need to go a step further. This is a full example:
const express = require('express');
const myExpress = Object.create(express().response, {
data: {
value: function(data) {
return this.status(200).json({status: true, data: data});
},
},
message: {
value: function(msg) {
return this.status(200).json({status: true, message: msg});
},
},
});
This way, you can create your express objects like this:
const app = express();
app.response = Object.create(myExpress);
From the response objects, you'll be able to call the message
and data
functions directly.