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

Support WebAssembly Component bindings, aka wasip2, in addition to javascript bindings #2294

Open
brooksmtownsend opened this issue May 20, 2024 · 4 comments · May be fixed by #2290
Open

Support WebAssembly Component bindings, aka wasip2, in addition to javascript bindings #2294

brooksmtownsend opened this issue May 20, 2024 · 4 comments · May be fixed by #2290
Labels
A-wasm Area: WASM. B-rfc Blocked: Request for comments. More discussion would help move this along.

Comments

@brooksmtownsend
Copy link

The current wasm implementation supports compiling to wasm with wasm_bindgen, which is meant to provide bindings for usage from JavaScript in the browser. This aligns with many of the concepts from wasi_preview_1 and uses the browser's fetch() API to actually make the request. This works great for the browser, now there's tons of applications that want to use a higher level API for making requests from Wasm and run them on the server. The next iteration of WASI, wasi_preview_2, is the perfect basis for this.

WASI Preview 2 released earlier this year WebAssembly/WASI#577 with a common set of standard interfaces, including wasi-http which provides an interface both for incoming and outgoing HTTP requests. What I would love is for reqwest to support binding to wasi:http/outgoing-handler which would let Rust devs compile reqwest directly to a Wasm component targeting p2. I am a maintainer of wasmCloud which uses wasi-http for it's requests and, as you can see in this sample, using a higher level library in Rust greatly simplifies the code.

I opened #2290 to start implementing this but I think there's a couple of questions to answer:

  1. How do we want to gate compiling for the browser v.s. compiling to a component? Is it feature flags, and if so, which one is the default? (It's worth noting there is a specific target for components, wasm32-wasip2, however this is a new target and doesn't properly denote the difference between "browser" wasm and a component)
  2. Does feat(wasm): add support for wasip2, aka webassembly components, using wasi-http #2290 look reasonable or should we approach the problem differently? Most of the logic happens in the client's fetch function, and you can see the translation from the reqwest::Request and the wasi::http::OutgoingRequest.
  3. Do we like the file organization in feat(wasm): add support for wasip2, aka webassembly components, using wasi-http #2290 with the refactor or prefer for components to be a new folder? WASI Http module #1956 contains a reference implementation with slightly old bindings with a different file structure

This PR is essentially a duplicate of #1956, I just promised to open another issue so we can dedup as necessary.

I think this PR is related to #1977 but it might not entirely supercede it since there's a deeper discussion on abstraction.

Thanks @seanmonstar for being receptive to the issue + change. Looking forward to the discussion!

@brooksmtownsend
Copy link
Author

Added example in #2290, and for additional clarity here's what's upcoming in terms of wasm32 targets in Rust. Eventually I think we can remove the feature flag and instead use the target as a differentiator of when to use the p1 bindings v.s. p2 bindings.

@brooksmtownsend
Copy link
Author

@seanmonstar would you like to see any additional commentary/fixes/thoughts here? Do you have any questions?

One question I have for you is if you think we could include this in the synchronous version of the crate, since wasip2 components don't technically native async we could avoid the use of the futures::block_on function.

@smndtrl
Copy link
Contributor

smndtrl commented Jun 13, 2024

One of the major issues I experienced with wasi-http experiments in reqwest is that the (non)overlap in API surface leads to issues with third party crates relying on reqwests non wasm target APIs. Especially cookies, proxies and tls are not available on wasi-http. What expectation should a user have in terms of using APIs and/or third party crates?

While I would be happy to have a 100% shim with warnings when features are not available when using the wasi-http, it might not be a good way to go.

@brooksmtownsend
Copy link
Author

@smndtrl I think your comment makes a lot of sense. With the current level of standard HTTP support for WASI, there's not really an expectation for a user to be able to use cookies/proxies/tls right now. We could always model that in terms of a different interface, but it would be up to the WebAssembly host to implement that and that doesn't belong in a general purpose library.

The reality right now is that this type of feature would make Wasm applications in Rust that use HTTP look a lot nicer, and it would only be a small step for existing Rust applications that hope to seamlessly swap over to the wasi-p2 target. The shim with warnings (or failure to compile) is essentially what I was thinking for the first pass here.

I'm going to spend a bit of effort making the PR smaller in scope to, hopefully, make the surface area smaller for testing + questions

@seanmonstar seanmonstar added B-rfc Blocked: Request for comments. More discussion would help move this along. A-wasm Area: WASM. labels Jun 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-wasm Area: WASM. B-rfc Blocked: Request for comments. More discussion would help move this along.
Projects
None yet
3 participants