Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Support modern web APIs (Request, Response, ReadableStream, WritableStream) in Express #288

Open
ChristophP opened this issue Oct 17, 2024 · 0 comments

Comments

@ChristophP
Copy link

ChristophP commented Oct 17, 2024

Proposal

In order for Express to modernize it's APIs and support Web Standards in addition to Node built-ints it would be great to have an API that let's one use

  • the built-in Request and Response from the fetch API instead of Node's http.request and http.response
  • the build-in web streams ReadableStream and WritableStream instead of Node's steam.Readable and stream.Writable

How could this look?

Basic Example

As an idea Express could expose this in a non-breaking way by offering an alternative to the app.use() function.

// req is a `Request` the fetch API, a new `Response` is returned
app.useWeb(async (req) => {
  const reqBody = await req.text();
  return new Response(`<h1>Hi from Express<h1/><p>${req.body}</p>`, { headers: { "content-type": "text/html" } })
});

Streaming Example

import fs from 'node:fs/promises';

const file = await open('./some/file/to/read');
// req is a `Request` the fetch API, a new `Response` is returned
app.useWeb(async (req) => {
  const nodeStream = await fs.createWriteStream('./some-data.json');

  return new Response(nodeStream.toWeb(), { headers: { "content-type": "application/json" } })
});

In types

The app.useWeb function could have the signature

(request: Request) => Response | Promise<Response>

Alternative design

If it it is difficult to mix and match the normal use with useWeb. Maybe and alternative approach could be to have a different API for creating the server.

const app = express.createAppWeb() // needs a better name
app.use(...) // this use function expects the signature from above

Compatibility

app.useWeb could serve as a compatibilty layer and normalize calls to use and useWeb under the hood. So under the hood express could continue to use node streams while it's possible to use web streams and fetch APIs as a user.

Benefits

NodeJS has adopted a lot of web standards in the past decade. It would be great for express to make it easy for users to use them.

Drawbacks

  • might increase the API surface of Express
  • some of the support NodeJS has for these APIs is still experimental. However, it seems like NodeJS is quite committed to supporting these new APIs

References

Deno has similar interface using Request/Response for Deno.serve

Open questions

  • how to deal with .next()?
  • how to deal with errors?

I realize supporting this might have bigger implications for the inner workings as well as API decisions of express, so this should be carefully considered

Thanks

Great to have Express 5 released ❤️

@UlisesGascon UlisesGascon transferred this issue from expressjs/express Oct 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant