Skip to content

Second middleware stack #2255

Closed
Closed
@rlidwka

Description

@rlidwka

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions