Expand description
§reqwest-cross
The reqwest-cross
crate (inspired by ehttp) provides a
wrapper around reqwest for ease of use in applications that
target BOTH native and wasm and do not want to block in the calling
task/thread, for example in a UI task/thread or game loop. This is achieved
by using callbacks. This crate provides a few options to choose from and the
one that fits best for you depends on what you need. A good way to get an
idea what level of abstraction would work for you is by looking at the
[examples][#examples]. I would say if you’re writing a larger application
then DataState can abstract away a lot of the boiler plate. In addition I
would prefer fetch_plus over fetch unless you don’t need the UI
callback and fetch_plus ends up as the one with more boiler plate. If
automated retires are desired see DataStateRetry which exposes similar
methods but with retry built in.
NOTE: At least 1 feature flag for native MUST be set to choose which runtime to use. Currently only Tokio is supported but if you want to use another runtime please open an issue on github and we’d be happy to add it. To communicate between the callback and the caller you can use various approaches such as:
- The helper type in this crate DataState see examples folder
- channels (used in examples)
Arc<Mutex<_>>
- promises and so on.
§Examples
For examples of how to use this crate see fetch, fetch_plus and the examples folder in the repo
§Feature Flags
default
— Enables the tokio runtime and reqwest’s default features. If default-features gets disabled do ensure you at least enable tls, unless you explicitly do not want tls support.reqwest_default
(enabled by default) — Enables reqwest’s default featuresnative-tokio
(enabled by default) — Sets tokio as the runtime to use for nativeyield_now
— Add a function that can be called to yield to the executor. This is only needed if you only have one thread and need to release it to prevent a deadlock because you are waiting on another future (as can be the case in WASM). If you are using a framework such as egui this may not be necessary as they already allow for other futures to make progress. But one test will quickly let you know either way. If the program freezes after you make a request then this can help.egui
— Add helper functions to [‘DataState’] to do egui boiler plate
The following enable a subset of reqwest’s features. If you need a feature that we didn’t include please open an issue and let us know and we’ll add it. In the mean while you can depend on reqwest directly with the same version as this crate and enable the feature. Because features are additive it will be enabled but note that if the version goes out of sync it will cause compilation issues.
default-tls
— Enables the feature with the same name on reqwestnative-tls
— Enables the feature with the same name on reqwestrustls-tls
— Enables the feature with the same name on reqwesthttp2
— Enables the feature with the same name on reqwestjson
— Enables the feature with the same name on reqwestcookies
— Enables the feature with the same name on reqwesthickory-dns
— Enables the feature with the same name on reqwestmultipart
— Enables the feature with the same name on reqwestsocks
— Enables the feature with the same name on reqweststream
— Enables the feature with the same name on reqwestbrotli
— Enables the feature with the same name on reqwestdeflate
— Enables the feature with the same name on reqwestgzip
— Enables the feature with the same name on reqwestzstd
— Enables the feature with the same name on reqwest
Exactly 1 of the “native-*” flags MUST be enabled to select which runtime to use for native. If one of the other options needs to be used instead of tokio then defaults must be disabled.
§Tradeoffs
§Exposing underlying framework that actually sends the requests
The currently selected approach of exposing and using reqwest::RequestBuilder is much more flexible than the fully isolated approach used by ehttp and is generally desirable as it allows for reuse of the same reqwest::Client as recommended by reqwest. However, since reqwest::Client is asynchronous it requires an available runtime. For wasm the spawning of the futures is handled by wasm-bindgen-futures but for local which runtime is specified using feature flags.
§How to run tokio on “secondary” thread
If you want to use the main thread for your UI and need to run tokio on a “secondary” thread I found this example helpful. I found it in this discussion, which had other suggested examples as well.
Re-exports§
pub use reqwest;
Modules§
- A channel for sending a single message between asynchronous tasks.
Structs§
- Used to represent data that is pending being available
- Automatically retries with a delay on failure until attempts are exhausted
Enums§
- Used to store a type that is not always available and we need to keep polling it to get it ready
- Represents the types of errors that can occur while using DataState
Traits§
- A future with the required bounds for the platform
- A function that receives the reqwest::Response and returns it to the application via some means (See examples for way it can be done)
- Provides a common way to specify the bounds errors are expected to meet
- An async func that accepts a reqwest::Response and returns a generic value
- A function able to be used as a Call Back to notify the UI that the request is ready
- Allowed return types
Functions§
- Performs a HTTP requests and calls the given callback when done with the result of the request. This is a more flexible API but requires more boilerplate, see fetch_plus which wraps a lot more of the boilerplate especially if you need a “wake_up” function. NB: Needs to use a callback to prevent blocking on the thread that initiates the fetch. Note: Instead of calling get like in the example you can use post, put, etc. (See reqwest::Client). Also see the examples folder for more complete examples.
- Wraps the call to fetch with the surrounding boilerplate.
- Spawns a future on the underlying runtime in a cross platform way (NB: the Send bound is removed in WASM)
- Attempts to provide a yield for executor currently in use. There doesn’t appear to be one available as yet for wasm_bindgen_futures so a workaround taken from https://github.com/rustwasm/wasm-bindgen/discussions/3476 is used