web-sys: The fetch API
This example uses the fetch API to make an HTTP request to the GitHub API and then parses the resulting JSON. _ [wasm-bindgen Guide]
Original [web-sys: The fetch API]
setup the project
cargo new fetch --lib
cd fetch
mkdir -p www/js www/html
cargo add wasm-bindgen js-sys wasm-bindgen-futures
cargo add web-sys -F "Headers, Request, RequestInit, RequestMode, Response, Window"
edit Cargo.toml to add crate-type
[lib]
crate-type = ["cdylib",]
And edit the web-sys
entry to [dependencies.web-sys]
web-sys = { version = "0.3.69", features = ["Headers", "Request",
"RequestInit", "RequestMode", "Response", "Window"] }
to
[dependencies.web-sys]
version = "0.3.69"
features = [
"Headers",
"Request",
"RequestInit",
"RequestMode",
"Response",
"Window",
]
in www/html/index.html
we have
<!doctype html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
<title>fetch: nobundle</title>
</head>
<body>
<p>The developer console should have log messages in it</p>
<script type="module" src="../js/index.js"></script>
</body>
</html>
and in www/js/index.js
import init, {run as rs_run} from "../pkg/fetch.js"
async function run() {
const wasm = await init();
const data = await rs_run("rustwasm/wasm-bindgen");
console.log(data);
console.log("The latest commit to the wasm-bindgen %s branch is:", data.name);
console.log("%s, authored by %s <%s>", data.commit.sha, data.commit.commit.author.name, data.commit.commit.author.email);
}
run();
/*
const rust = import('./pkg');
rust
.then(m => {
return m.run("rustwasm/wasm-bindgen").then((data) => {
console.log(data);
console.log("The latest commit to the wasm-bindgen %s branch is:", data.name);
console.log("%s, authored by %s <%s>", data.commit.sha, data.commit.commit.author.name, data.commit.commit.author.email);
})
})
.catch(console.error);
*/
Rust/wasm side
#![allow(unused)] fn main() { // src/lib.rs use wasm_bindgen::prelude::*; use wasm_bindgen_futures::JsFuture; use web_sys::{Request, RequestInit, RequestMode, Response}; #[wasm_bindgen] pub async fn run(repo: String) -> Result<JsValue, JsValue> { let mut opts = RequestInit::new(); opts.method("GET"); opts.mode(RequestMode::Cors); let url = format!("https://api.github.com/repos/{}/branches/master", repo); let request = Request::new_with_str_and_init(&url, &opts)?; request .headers() .set("Accept", "application/vnd.github.v3+json")?; let window = web_sys::window().unwrap(); let resp_value = JsFuture::from(window.fetch_with_request(&request)).await?; // `resp_value` is a `Response` object. assert!(resp_value.is_instance_of::<Response>()); let resp: Response = resp_value.dyn_into().unwrap(); // Convert this other `Promise` into a rust `Future`. let json = JsFuture::from(resp.json()?).await?; // Send the JSON response back to JS. Ok(json) } }
build and serve
wasm-pack build --target web --no-typescript --out-dir www/pkg
serve: http www
open: index.html
firefox http://localhost:8000/html/