-
Notifications
You must be signed in to change notification settings - Fork 145
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
utility crate: fetch and making HTTP requests #4
Comments
Can we make the dual to https://crates.io/crates/http-service ? |
maybe there are Bonus points to be had for developing an crate that can also work outside of the browser/JS context. For example, if someone were to develop a library for the github API or something, they might want their crate to be usable as both a standard crate linked into a CLI application, or as a wasm crate. |
Even more bonus points for contributing wasm support to an already established library? seanmonstar/reqwest#288 |
Can something like Request be modified to support wasm without reinventing it, or does it need to use something like web_sys::request_with_... ? @Pauan wrote a general wasm fetch lib using Futures, with a nice API |
Sweet! Care to share a link? |
@Pauan Want to submit a PR? |
@David-OConnor I'm not sure if that's a good idea. I think we should first figure out whether we're going to be creating something new or contributing to an existing project, and I also think we should discuss a bit about the API. |
I would be interested in contributing "mid-level" bindings (as discussed in issue #27) for XHR. As it would be a straightforward wrapper for |
@tomhoule great! I think the next thing we need to push this forward is an API design proposal (here is a template you can use: https://github.com/fitzgen/gloo/blob/master/.github/ISSUE_TEMPLATE/propose_design.md) For the "mid-level" bindings I expect the design and consensus work to be fairly straightforward. One question I do have right off the bat, that I think the proposal should address and/or leave a TODO hole for, is whether we want to build atop XHR or |
That's a really good question! Fetch is the new high-level "blessed" API, but I don't think it fully supports all of the features of XHR, so maybe having both is a good idea? Also, since fetch uses Promises, it matches very naturally to Rust Futures, so we could treat XHR as the "mid-level" API, and fetch as the "high-level" API. |
My specific use-case with XHR at the moment is file uploads. To the best of my knowledge fetch doesn't support tracking upload progress, so it would make sense to have both. As the fetch API gets more features it will be the better option however (it is already, for many use-cases). The two APIs are very different so a common wrapper (XHR and fetch) would definitely be in "high level" territory in my opinion. It could look something like axios, but I would be happy to just have the callback-based XHR API with nicer Rust types for now. One more thought on @Pauan's last comment: if the crate structure gloo adopts ends up being |
API design proposal for XHR: #37 |
In JavaScript / Node the xhr and xhr-request crates have been a joy to work with. In particular one thing I think they nailed is that they managed to evade the "double await" design that the newer fetch API introduced. fetch problems // text
let req = await fetch('/endpoint')
let res = await req.text()
console.log(res)
//json
let req = await fetch('/endpoint')
let res = await req.json()
console.log(JSON.stringify(res)) The temporary binding exists so users can decide how to parse a result based on the headers. This is not common though, and forces everyone to name the temporary binding rather than being able to chain and fit it on one line. xhr // text
let res = await xhr('/endpoint')
console.log(res)
// json
let res = await xhr('/endpoint', { json: true })
console.log(JSON.stringify(res)) bringing it to Rust // text
let res = xhr::get("/endpoint").send().await?;
dbg!(res);
// json
struct User { name: String }
let user: User = xhr::get("/endpoint").send_json().await?;
dbg!(user); This is not to say this should be the only API possible. But I think that if we manage to make most common interactions (JSON, forms, multipart, etc.) available through convenient APIs, then we'll be able to create a pretty compelling story for making HTTP requests in Rust conclusion |
Having a good http client will be a key part of making gloo a success, but it is a very big job. I would propose that we first create nice zero-cost libraries around Once we are happy with those, we could begin to specify how a client would look. The first piece of work would be to do a review of existing solutions (e.g. reqwest, hyper, node, haskell, whatever is considered useful) and write that up. That would be a starting point for designing the api for the request library. |
Thoughts on getting a not-perfect-but workable module released? |
Oh yeah, I forgot to update this issue but we released https://docs.rs/surf/1.0.2/surf/ a few weeks ago, which works in the browser out of the box (: |
What's the status of this? I think creating a low level library built on top of the http crate and JS's fetch API should be fairly simple. |
https://docs.rs/http-client/1.0.0/http_client/ has now been published! |
That seems like a decent start, but it seems to ignore all request headers. But I guess I might use this. |
Seed's fetch module API docs, for ref. Built on |
Both of these seem unfitting for the job. The Seed implementation is not based on the http crate (and is a whole framework, not just a tiny wrapper around fetch) and http-client is too immature and stuck with futures 0.1. I'll go with my own implementation in the meantime. |
We're using futures-preview 0.3.0; with std futures + the current shape of the stream traits. The only reason why we haven't upgrade yet to futures 0.3.0 proper is because the curl library we rely on hasn't moved over yet, but that work is currently happening and should be done in a few days. |
I'm trying to push forward this issue by adding webidl iterator support to wasm-bindgen at rustwasm/wasm-bindgen#1913. Using iterators seems to be the only way to get at the full list of headers in the response. |
Nice, I'm also slowing preparing a gloo-http PR. I've been using my implementation for quite a bit and it seems pretty robust now. |
@CryZe nice I've had a look at your work on your github and it looks cool! I haven't written this up yet, but i was thinking of proposing that the http stack in gloo looked something like
Of course the alternative is to wrap the whole thing into |
Yeah I'll look into making the design closer to this. However XHR is probably out of scope for that PR at least (and maybe in general? Pretty sure every wasm compatible browser has fetch). |
@CryZe yeah now you say that I realise you're right and I can't see any reason to support xhr. Maybe just gloo-http using fetch then. :) |
This comment was marked as abuse.
This comment was marked as abuse.
That's actually a good point. Actually my implementation was initially based on XHR and apparently you only get a very raw unparsed view of the response headers (unless I missed something). So we may need to bring the httparse crate for that implementation. |
@dakom if we were only supporting up-to-date browsers, do |
This comment was marked as abuse.
This comment was marked as abuse.
This comment was marked as abuse.
This comment was marked as abuse.
Why do we need that when |
One reason is that |
has there been any progress on the issue? |
@vnermolaev, I have written a crate, reqwasm, specifically for this. Please take a look. |
We have two options to move forward here:
pub use reqwasm::http as fetch
pub use reqwasm::websocket as websocket I personally prefer the latter approach as it allows reqwasm to grow on it own, e.g. adding framework support behind feature flags, etc while also allowing it to be used from gloo. Thoughts? |
|
* redo websockets * docs + tests * remove gloo-console * fix CI * Add getters for the underlying WebSocket fields * better API * better API part 2 electric boogaloo
* Initial commit * provide a better interface for errors, rename `RequestMethod` to `Method` * remove method for array buffer and blob in favor of as_raw * prepare for release * add CI, update readme * hide JsError in the docs * fix CI? * Install wasm-pack in CI * misc * websocket API Fixes: ranile/reqwasm#1 * add tests for websocket * update documentation, prepare for release * fix mistake in documentation * Rewrite WebSockets code (#4) * redo websockets * docs + tests * remove gloo-console * fix CI * Add getters for the underlying WebSocket fields * better API * better API part 2 electric boogaloo * deserialize Blob to Vec<u8> (#9) * Update to Rust 2021 and use JsError from gloo-utils (#10) * Update to Rust 2021 and use JsError from gloo-utils * use new toolchain * Add response.binary method to obtain response as Vec<u8> Fixes: ranile/reqwasm#7 * Remove `Clone` impl from WebSocket. When the WebSocket is used with frameworks, passed down as props, it might be `drop`ed automatically, which closes the WebSocket connection. Initially `Clone` was added so sender and receiver can be in different `spawn_local`s but it turns out that `StreamExt::split` solves that problem very well. See #13 for more information about the issue * Rustfmt + ignore editor config files * Fix onclose handling (#14) * feat: feature gate json, websocket and http; enable them by default (#16) * feat: feature gate json support * feat: feature gate weboscket api * ci: check websocket and json features seperately in CI, check no default features * feat: feature gate the http API * refactor: use futures-core and futures-sink instead of depending on whole of futures * ci: test http feature seperately in CI * fix: only compile error conversion funcs if either APIs are enabled * fix: add futures to dev-deps for tests, fix doc test * 0.3.0 * Fix outdated/missing docs * 0.3.1 * Change edition from 2021 to 2018 (#18) * Change edition from 2021 to 2018 * Fix missing import due to edition 2021 prelude * hopefully this will fix the issue (#19) * There's no message * Replace `async-broadcast` with `futures-channel::mpsc` (#21) We no longer need a multi-producer-multi-consumer channel. There's only one consumer as of ranile/reqwasm@445e9a5 * Release 0.4.0 * Fix message ordering not being preserved (#29) The websocket specification guarantees that messages are received in the same order they are sent. The implementation in this library can violate this guarantee because messages are parsed in a spawn_local block before being sent over the channel. When multiple messages are received before the next executor tick the scheduling order of the futures is unspecified. We fix this by performing all operations synchronously. The only part where async is needed is the conversion of Blob to ArrayBuffer which we obsolete by setting the websocket to always receive binary data as ArrayBuffer. * 0.4.1 * move files for gloo merge * remove licence files * gloo-specific patches * fix CI * re-export net from gloo Co-authored-by: Michael Hueschen <mhuesch@users.noreply.github.com> Co-authored-by: Stepan Henek <stepan+github@henek.name> Co-authored-by: Yusuf Bera Ertan <y.bera003.06@protonmail.com> Co-authored-by: Luke Chu <37006668+lukechu10@users.noreply.github.com> Co-authored-by: Valentin <vakevk+github@gmail.com>
We should wrap up the fetch API into a nice Rust-y utility crate!
The text was updated successfully, but these errors were encountered: