Description
Just sharing my thoughts about res.send()
mentioned in #2249 (comment)
This is just an idea, and it has a lot of flaws as is, but maybe somebody would find it useful.
So, right now res.send()
terminates middleware stack. next()
handler is not called, so no middlewares won't be executed. Well, except for those who monkey-patches res.send()
of course, but people usually see it as a hack.
Currently all middlewares are supposed to be executed before result of the request is known.
Here is a typical express application with a few middlewares.
app.use(bodyParser)
app.use(etagify)
app.use(compress)
app.use(function convert_result_to_yaml(req, res, next) {
// I'm typing this from memory and realizing that I
// remember this pattern a lot better that I would like to
var _send = res.send
res.send = function(data) {
res.send = _send
data = YAML.stringify(data)
res.send(data)
}
})
app.get('/', function(req, res) {
res.send({hello: 'world'})
})
Please note that etagify, compress and that weird custom formatter are usually only overriding res.send() and their main work is done after res.send is executed.
And because of the way how they work, etagify is specified before compress, but it is actually called after it.
Idea: res.send(data)
could pass the data to a second middleware stack. This stack would know that the result of the request is ready and perform some operations over it.
app.use(bodyParser)
app.get('/', function(req, res) {
res.send({hello: 'world'})
})
app.final(function convert_result_to_yaml(req, res, data, next) {
// `data` would be an object/string/whatever res.send() is called with
//
// note changed signature of this and next functions
next(null, YAML.stringify(data))
})
app.final(compress)
app.final(etagify)
Which some people might find more clear.
Note that real-world middlewares are much more complex because of the streaming, and I don't know how to deal with this yet. Well, maybe do res.send(Stream)
and make use of transform streams.