The fetch API
View full source code or view the compiled example online
This example uses the fetch API to make an HTTP request to the GitHub API and
then parses the resulting JSON.
Cargo.toml
The Cargo.toml enables a number of features related to the fetch API and
types used: Headers, Request, etc. It also enables wasm-bindgen's serde
support.
[package]
name = "fetch"
version = "0.1.0"
authors = ["The wasm-bindgen Developers"]
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
futures = "0.1.20"
wasm-bindgen = { version = "0.2.33", features = ["serde-serialize"] }
js-sys = "0.3.10"
wasm-bindgen-futures = "0.3.10"
serde = { version = "1.0.80", features = ["derive"] }
serde_derive = "^1.0.59"
[dependencies.web-sys]
version = "0.3.4"
features = [
'Headers',
'Request',
'RequestInit',
'RequestMode',
'Response',
'Window',
]
src/lib.rs
# #![allow(unused_variables)] #fn main() { use futures::{future, Future}; use js_sys::Promise; use wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; use wasm_bindgen_futures::future_to_promise; use wasm_bindgen_futures::JsFuture; use web_sys::{Request, RequestInit, RequestMode, Response}; use serde::{Deserialize, Serialize}; /// A struct to hold some data from the github Branch API. /// /// Note how we don't have to define every member -- serde will ignore extra /// data when deserializing #[derive(Debug, Serialize, Deserialize)] pub struct Branch { pub name: String, pub commit: Commit, } #[derive(Debug, Serialize, Deserialize)] pub struct Commit { pub sha: String, pub commit: CommitDetails, } #[derive(Debug, Serialize, Deserialize)] pub struct CommitDetails { pub author: Signature, pub committer: Signature, } #[derive(Debug, Serialize, Deserialize)] pub struct Signature { pub name: String, pub email: String, } #[wasm_bindgen] pub fn run() -> Promise { let mut opts = RequestInit::new(); opts.method("GET"); opts.mode(RequestMode::Cors); let request = Request::new_with_str_and_init( "https://api.github.com/repos/rustwasm/wasm-bindgen/branches/master", &opts, ) .unwrap(); request .headers() .set("Accept", "application/vnd.github.v3+json") .unwrap(); let window = web_sys::window().unwrap(); let request_promise = window.fetch_with_request(&request); let future = JsFuture::from(request_promise) .and_then(|resp_value| { // `resp_value` is a `Response` object. assert!(resp_value.is_instance_of::<Response>()); let resp: Response = resp_value.dyn_into().unwrap(); resp.json() }) .and_then(|json_value: Promise| { // Convert this other `Promise` into a rust `Future`. JsFuture::from(json_value) }) .and_then(|json| { // Use serde to parse the JSON into a struct. let branch_info: Branch = json.into_serde().unwrap(); // Send the `Branch` struct back to JS as an `Object`. future::ok(JsValue::from_serde(&branch_info).unwrap()) }); // Convert this Rust `Future` back into a JS `Promise`. future_to_promise(future) } #}