Crate reqwest_cross

Source
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:

§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 features
  • native-tokio (enabled by default) — Sets tokio as the runtime to use for native
  • yield_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 reqwest
  • native-tls — Enables the feature with the same name on reqwest
  • rustls-tls — Enables the feature with the same name on reqwest
  • http2 — Enables the feature with the same name on reqwest
  • json — Enables the feature with the same name on reqwest
  • cookies — Enables the feature with the same name on reqwest
  • hickory-dns — Enables the feature with the same name on reqwest
  • multipart — Enables the feature with the same name on reqwest
  • socks — Enables the feature with the same name on reqwest
  • stream — Enables the feature with the same name on reqwest
  • brotli — Enables the feature with the same name on reqwest
  • deflate — Enables the feature with the same name on reqwest
  • gzip — Enables the feature with the same name on reqwest
  • zstd — 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§

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§

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