Skip to content

Decoupling express.request and express.response from express application #2812

Open
@aoberoi

Description

@aoberoi

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 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) 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 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 issues 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?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions