简体   繁体   中英

It is possible to enhance the express.js req and res variables without using a middleware function?

I'm working in a restful service using express.js and i want to enhance the req and res variables so for example you could write something like

app.use(function (req, res, next) {
    res.Ok = function (data) {
        res.status(200).send(data);
    };

    res.InternalError = function (err) {
        res.status(500).send(err);
    };
});

And later

router.get('/foo', function (req, res) {
    res.Ok('foo');
})

This will send 'foo' in the body of the response and set the status code to 200 and is working perfectly.

My first question is if it is possible to add such functionality without a middleware function, lets say in a property or the prototype of the app variable?

The second question is if there are performance issues if you add many functionality with middleware functions at the app level. Are this functions attached to the request and response object per request or once on the application startup?

I know the Sails framework already do this but I'm wondering if they use middleware functions as well.

I keep digging and turns out that the request and response object are exposed in express using the __proto__ property.

var express = require('express'),
app = express();

app.response.__proto__.foo = function (data) {
    this.status(200).send(data);
};

And later in the router

router.get('/foo', function (req, res, next) {
    res.foo('test');
});

This will print test in your browser so it is possible to add functionality without using any middleware.

Note: I'm sure there are some drawbacks to this approach (overwriting express predefined properties, for example) but for testing purposes and adding very simple functionality I think is slightly better in terms of performance.

I'm not aware of any other way than using middleware. But in my opinion you could do the following to achieve nearly the same thing.

// Some Route
router.get('/foo', function(req, res, next) {
 // ...
 if(err) {
   res.status(500);
   return next(err);
 }
 return res.send('ok');
});

// Another route
router.get('/bar', function(req, res, next) {
  // ...
  if(badUserId) {
    res.status(400);
    return next('Invalid userId.');
  }
  req.result = 'hello';
  return next();
});

router.use(function(req, res) {
  // I prefer to send the result in the route but an
  // approach like this could work
  return res.send(req.result);
});

// Error Middleware
router.use(function(err, req, res, next) {
  if(res.statusCode === 500) {
    // Log the error here
    return res.send('Internal server error');
  } else {
    return res.send(err);
  }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM