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

stream: implement fetch body mixin on Readable #39520

Closed
wants to merge 17 commits into from

Conversation

ronag
Copy link
Member

@ronag ronag commented Jul 25, 2021

Make Readable expose the fetch boxy mixin API.

Bypasses webstream glue when possible.

This also makes conversion to webstream faster when the stream is not consumed through Readable by bypassing much of the Readable logic.

Refs: https://fetch.spec.whatwg.org/#body-mixin

@ronag ronag requested review from mcollina and jasnell July 25, 2021 19:01
@ronag ronag force-pushed the body-mixin-readable branch 3 times, most recently from ad42494 to bdc3d17 Compare July 25, 2021 19:05
@ronag
Copy link
Member Author

ronag commented Jul 25, 2021

Not sure if adding properties on core classes should be semver-major?

@ronag
Copy link
Member Author

ronag commented Jul 25, 2021

Will work on test if there is positive feedback on this approach.

@nodejs-github-bot nodejs-github-bot added the needs-ci PRs that need a full CI run. label Jul 25, 2021
@ronag

This comment has been minimized.

@ronag ronag force-pushed the body-mixin-readable branch 4 times, most recently from 9e6a765 to 80db7ac Compare July 26, 2021 06:48
@ronag
Copy link
Member Author

ronag commented Jul 26, 2021

@nodejs/streams

@ronag ronag force-pushed the body-mixin-readable branch 14 times, most recently from e101b1d to e038fba Compare July 26, 2021 07:20
@ronag
Copy link
Member Author

ronag commented Jul 30, 2021

@ronag
Copy link
Member Author

ronag commented Jul 30, 2021

The express stuff can be workaround through, but the superagent issue is maybe more difficult... https://github.com/visionmedia/superagent/blob/master/src/node/response.js#L36

ronag added a commit to ronag/superagent that referenced this pull request Jul 30, 2021
Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is doable without massive ecosystem breakage. We need also to consider Duplex inherit from Readable, and therefore it will inherit a .json() method. However express provides a res.json() method, which will quickly get confused with this.

I think we are better off with a separate class, or some other utility Readable.toFetchBody(readable).json() or readable.toFetchBody().json().

@ronag
Copy link
Member Author

ronag commented Jul 30, 2021

I don't think this is doable without massive ecosystem breakage. We need also to consider Duplex inherit from Readable, and therefore it will inherit a .json() method. However express provides a res.json() method, which will quickly get confused with this.

I think we are better off with a separate class, or some other utility Readable.toFetchBody(readable).json() or readable.toFetchBody().json().

That kind of kills the use case for me. Can we put it behind a flag passed to the constructor which is disabled by default?

@mcollina
Copy link
Member

That kind of kills the use case for me. Can we put it behind a flag passed to the constructor which is disabled by default?

This means that most Node.js core object would not have those. I'm not sure that's what you would like achieve either.
What's your use case specifically?

ronag added a commit to nodejs/undici that referenced this pull request Jul 30, 2021
Port over PR from node core. It will not be possible to land
these changes on core due to ecosystem breakage.

Refs: nodejs/node#39520
@ronag
Copy link
Member Author

ronag commented Jul 30, 2021

That kind of kills the use case for me. Can we put it behind a flag passed to the constructor which is disabled by default?

This means that most Node.js core object would not have those. I'm not sure that's what you would like achieve either.
What's your use case specifically?

We wanted to support body mixin in undici request API without causing breaking change. Also it makes sense there in general.

@ronag
Copy link
Member Author

ronag commented Jul 30, 2021

Taking another look at this I believe this can actually live outside of core (at least for my intended use case). nodejs/undici#907

@ronag
Copy link
Member Author

ronag commented Jul 30, 2021

Given the issue described in #39543, can we at least keep bodyUsed (under some other name if necessary)? Also possibly this[kReading] under some public API (maybe can be merged into readableDidRead)?

@ronag
Copy link
Member Author

ronag commented Jul 30, 2021

I'm closing this. It's not possible to do it this way due ecosystem conflicts. If someone wants to pick it up in some other form feel free to branch off this or create an issue for discussion. I'm moving over to extending Readable in user land where needed. nodejs/undici#907

@ronag ronag closed this Jul 30, 2021
@RomainLanz
Copy link
Contributor

RomainLanz commented Jul 30, 2021

If I may give my feedback on this.

I am sad that this is closed partially due to an outdated framework/library (express) that is already not working with modern JavaScript (AsyncFunction are causing memory leaks and crashes).

There are no reason not to add this feature inside the core, especially if it is part of a major release (meaning their will be breaking changes).

Libraries and frameworks need to adapt. It is not the role of Node.js to be adjusted.

Everyone knows that patching/modifying core/native objects is a very bad practice. We should not rely on people who are doing that to keep us from improving Node.js core.

ronag added a commit to nodejs/undici that referenced this pull request Jul 31, 2021
* stream: implement body mixin on Readable

Port over PR from node core. It will not be possible to land
these changes on core due to ecosystem breakage.

Refs: nodejs/node#39520

* fixup: tests

* fixup

* fixup

* fixuP

* fixuP

* fixup: remove node specific stuff

* fixup: formData

* fixup: simplify

* fixup

* fixup

* fixup

* fixup: README

* fixup
@benjamingr
Copy link
Member

Libraries and frameworks need to adapt. It is not the role of Node.js to be adjusted.

I see (and appreciate) the sentiment but that's not the sort of burden of responsibility Node.js has. Express is used by millions of projects and we can't just break it.

@ronag

What about a mixinBody or similar method that enriches Readable (or a constructor option that opts into this)?

@ronag
Copy link
Member Author

ronag commented Aug 2, 2021

What about a mixinBody or similar method that enriches Readable (or a constructor option that opts into this)?

I'm good with either.

@ronag
Copy link
Member Author

ronag commented Aug 2, 2021

@benjamingr something like 1b7f509?

@benjamingr
Copy link
Member

@ronag exactly :)

@benjamingr
Copy link
Member

Then different kinds of streams can opt-into this by default (so http IncomingRequest stream won't be able to by default but http.get might etc)

@mcollina
Copy link
Member

mcollina commented Aug 2, 2021

Then different kinds of streams can opt-into this by default (so http IncomingRequest stream won't be able to by default but http.get might etc)

This will make the API even harder to learn/use for folks.

@benjamingr
Copy link
Member

What do you suggest instead?

@jakearchibald
Copy link

Could there just be a module of stream consumers?

import { asJson } from 'stream-readers';

const data = await asJson(stream);

I might be missing some context around this PR.

@Mesteery
Copy link
Contributor

Mesteery commented Aug 2, 2021

Could there just be a module of stream consumers?

#39594

niftylettuce pushed a commit to ladjs/superagent that referenced this pull request Jan 18, 2022
KhafraDev pushed a commit to KhafraDev/undici that referenced this pull request Jun 23, 2022
* stream: implement body mixin on Readable

Port over PR from node core. It will not be possible to land
these changes on core due to ecosystem breakage.

Refs: nodejs/node#39520

* fixup: tests

* fixup

* fixup

* fixuP

* fixuP

* fixup: remove node specific stuff

* fixup: formData

* fixup: simplify

* fixup

* fixup

* fixup

* fixup: README

* fixup
Morita0711 added a commit to Morita0711/npm-superurgent that referenced this pull request Jul 3, 2022
crysmags pushed a commit to crysmags/undici that referenced this pull request Feb 27, 2024
* stream: implement body mixin on Readable

Port over PR from node core. It will not be possible to land
these changes on core due to ecosystem breakage.

Refs: nodejs/node#39520

* fixup: tests

* fixup

* fixup

* fixuP

* fixuP

* fixup: remove node specific stuff

* fixup: formData

* fixup: simplify

* fixup

* fixup

* fixup

* fixup: README

* fixup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready PRs that have at least one approval, no pending requests for changes, and a CI started. notable-change PRs with changes that should be highlighted in changelogs. semver-minor PRs that contain new features and should be released in the next minor version. stream Issues and PRs related to the stream subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.