Decoupling express.request and express.response from express application
- Dominant language
- JavaScript
- Stars
- 69.5k
- Forks
- 25k
- Avg merge
- 4d 20h
- Merged PRs (30d)
- 9
Description
I'd like to be able to use `express.request` and `express.response` outside of an express `application` "instance". This means I'd be able to use them as prototypes for my own request and response objects. Additionally, I'd like to also define which objects they delegate to for their prototypes (I understand this last part [is possible already](https://github.com/strongloop/express/issues/2805#issuecomment-156841207) but its not first-class and it won't work in an ES2015 world where imports are read-only).
I'm a big fan of the work that was done to decouple the router implementation into its own module so that it no longer assumes the presence of an express application. I believe what I am proposing is in the spirit of that effort.
A couple use cases I'm hoping to address:
- Testing for standalone router: I have a router which depends on its request and response arguments to implement the `express.request` and `express.response` interfaces. I'd like to write unit tests that are minimal, so I don't want to initialize an express application, nor do I want it to listen on a port or socket. Ideally, I could create some request and response objects directly from the express prototypes, and also plug in a "mock" for `http.IncomingMessage` and `http.ServerResponse` (that [don't need to actually do any networking](https://www.npmjs.com/package/mock-http)) to be one level up the prototype chain. Then I could just invoke my router's `handle()` method with the arguments I've constructed and set up assertions on the behavior. This is currently not possible because both request and response have methods that read settings from `this.app`. I've take a look at the tests for [pillarjs/router](https://github.com/pillarjs/router) and they seem to be limited to only use API on request and response that are provided by node core.
- Extensibility: I've seen a [few](https://github.com/strongloop/express/issues/2805) [issues](https://github.com/strongloop/express/issues/2781) on the tracker that are essentially asking for the ability to rewire request and response to expose more or different functionality. Its been noted that the design of express was to be a thin wrapper on top of the node core HTTP API, and thats where the limitations come from. If instead of directly using private API of `http.IncomingMessage` and `http.ServerResponse`, we had a declared interface (one that the aforementioned types already adhere to or do so through a thin adapter) for what `express.request` and `express.response` rely on up the prototype chain, we could enable much more innovation in the ecosystem. Express would also benefit from seeing experimentation on those layers and adopt proven and useful extensions back into its core.
Open Questions:
- If response and request don't read its settings from application, where do they read it from?
- What is the role of application when router (middleware), request, and response don't need it? Is it just a convenience for wiring things up in the "default" way?
Contributor guide
Assessment
This issue has not been assessed yet.