Skip to content

Commit

Permalink
Merge pull request #3 from wacker-dev/examples
Browse files Browse the repository at this point in the history
Add examples
  • Loading branch information
iawia002 authored Jun 7, 2024
2 parents 2e49a9a + eefe86e commit e6d932d
Show file tree
Hide file tree
Showing 12 changed files with 344 additions and 3 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"waki-macros",
"test-programs",
]
exclude = ["examples"]

[workspace.package]
version = "0.2.0"
Expand Down
3 changes: 0 additions & 3 deletions examples/README.md

This file was deleted.

17 changes: 17 additions & 0 deletions examples/client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "http-client"
version = "0.0.0"
edition = "2021"
publish = false

[package.metadata.component]
adapter = "wasi_snapshot_preview1.command.wasm"

[dependencies]
waki = { version = "0.2.0", features = ["json"] }
serde = { version = "1.0.202", features = ["derive"] }

# reduce wasm binary size
[profile.release]
lto = true
strip = "symbols"
114 changes: 114 additions & 0 deletions examples/client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# http-client

This example is built using the [WASI Preview 2 API](https://github.com/WebAssembly/wasi-http)
with the [waki](https://github.com/wacker-dev/waki) library.

## Build

First, install [cargo component](https://github.com/bytecodealliance/cargo-component):

```
cargo install cargo-component@0.11.0
```

Then execute the following command to compile it into a WASM program:

```
$ cargo component build
```

Or use `--release` option to build it in release mode:

```
$ cargo component build --release
```

## Run

After compilation, you can use [wasmtime](https://github.com/bytecodealliance/wasmtime) to run it:

```
$ wasmtime -S http target/wasm32-wasi/debug/http-client.wasm
GET https://httpbin.org/get, status code: 200, body:
{
"args": {
"a": "b"
},
"headers": {
"Accept": "*/*",
"Content-Type": "application/json",
"Host": "httpbin.org",
"X-Amzn-Trace-Id": "..."
},
"origin": "...",
"url": "https://httpbin.org/get?a=b"
}
GET https://httpbin.org/get, status code: 200, body:
Data { origin: "117.172.222.76", url: "https://httpbin.org/get" }
GET https://httpbin.org/range, status code: 200, body:
abcdefghij
klmnopqrst
POST https://httpbin.org/post, status code: 200, body:
{
"args": {},
"data": "{\"data\":\"hello\"}",
"files": {},
"form": {},
"headers": {
"Content-Length": "16",
"Content-Type": "application/json",
"Host": "httpbin.org",
"X-Amzn-Trace-Id": "..."
},
"json": {
"data": "hello"
},
"origin": "...",
"url": "https://httpbin.org/post"
}
POST https://httpbin.org/post, status code: 200, body:
{
"args": {},
"data": "",
"files": {},
"form": {
"a": "b",
"c": ""
},
"headers": {
"Content-Length": "6",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"X-Amzn-Trace-Id": "..."
},
"json": null,
"origin": "...",
"url": "https://httpbin.org/post"
}
POST https://httpbin.org/post, status code: 200, body:
{
"args": {},
"data": "",
"files": {
"field2": "hello"
},
"form": {
"field1": "value1"
},
"headers": {
"Content-Length": "181",
"Content-Type": "multipart/form-data; boundary=boundary",
"Host": "httpbin.org",
"X-Amzn-Trace-Id": "..."
},
"json": null,
"origin": "...",
"url": "https://httpbin.org/post"
}
```
18 changes: 18 additions & 0 deletions examples/client/src/bindings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Generated by `wit-bindgen` 0.24.0. DO NOT EDIT!
// Options used:

#[cfg(target_arch = "wasm32")]
#[link_section = "component-type:wit-bindgen:0.24.0:http-client:encoded world"]
#[doc(hidden)]
pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 173] = *b"\
\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07,\x01A\x02\x01A\0\x04\
\x01!component:http-client/http-client\x04\0\x0b\x11\x01\0\x0bhttp-client\x03\0\0\
\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-component\x070.202.0\x10wit-bind\
gen-rust\x060.24.0";

#[inline(never)]
#[doc(hidden)]
#[cfg(target_arch = "wasm32")]
pub fn __link_custom_section_describing_imports() {
wit_bindgen_rt::maybe_link_cabi_realloc();
}
101 changes: 101 additions & 0 deletions examples/client/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use serde::Deserialize;
use std::collections::HashMap;
use std::time::Duration;
use waki::Client;

#[derive(Debug, Deserialize)]
#[allow(dead_code)]
struct Data {
origin: String,
url: String,
}

fn main() {
// get with query
let resp = Client::new()
.get("https://httpbin.org/get?a=b")
.headers([("Content-Type", "application/json"), ("Accept", "*/*")])
.send()
.unwrap();
println!(
"GET https://httpbin.org/get, status code: {}, body:\n{}",
resp.status_code(),
String::from_utf8(resp.body().unwrap()).unwrap()
);

// get with json response
let resp = Client::new().get("https://httpbin.org/get").send().unwrap();
let status = resp.status_code();
let json_data = resp.json::<Data>().unwrap();
println!(
"GET https://httpbin.org/get, status code: {}, body:\n{:?}\n",
status, json_data,
);

// play with the response chunk
let resp = Client::new()
.get("https://httpbin.org/range/20")
.query(&[("duration", "5"), ("chunk_size", "10")])
.send()
.unwrap();
println!(
"GET https://httpbin.org/range, status code: {}, body:",
resp.status_code()
);
while let Some(chunk) = resp.chunk(1024).unwrap() {
println!("{}", String::from_utf8(chunk).unwrap());
}
println!();

// post with json data
let resp = Client::new()
.post("https://httpbin.org/post")
.json(&HashMap::from([("data", "hello")]))
.connect_timeout(Duration::from_secs(5))
.send()
.unwrap();
println!(
"POST https://httpbin.org/post, status code: {}, body:\n{}",
resp.status_code(),
String::from_utf8(resp.body().unwrap()).unwrap()
);

// post with form data
let resp = Client::new()
.post("https://httpbin.org/post")
.form(&[("a", "b"), ("c", "")])
.connect_timeout(Duration::from_secs(5))
.send()
.unwrap();
println!(
"POST https://httpbin.org/post, status code: {}, body:\n{}",
resp.status_code(),
String::from_utf8(resp.body().unwrap()).unwrap()
);

// post with file form data
let resp = Client::new()
.post("https://httpbin.org/post")
.header("Content-Type", "multipart/form-data; boundary=boundary")
.body(
"--boundary
Content-Disposition: form-data; name=field1
value1
--boundary
Content-Disposition: form-data; name=field2; filename=file.txt
Content-Type: text/plain
hello
--boundary--"
.as_bytes(),
)
.connect_timeout(Duration::from_secs(5))
.send()
.unwrap();
println!(
"POST https://httpbin.org/post, status code: {}, body:\n{}",
resp.status_code(),
String::from_utf8(resp.body().unwrap()).unwrap()
);
}
Binary file not shown.
19 changes: 19 additions & 0 deletions examples/server/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "http-server"
version = "0.1.0"
edition = "2021"
publish = false

[lib]
crate-type = ["cdylib"]

[package.metadata.component]
adapter = "wasi_snapshot_preview1.proxy.wasm"

[dependencies]
waki = "0.2.0"

# reduce wasm binary size
[profile.release]
lto = true
strip = "symbols"
41 changes: 41 additions & 0 deletions examples/server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# http-server

This example is built using the [WASI Preview 2 API](https://github.com/WebAssembly/wasi-http)
with the [waki](https://github.com/wacker-dev/waki) library.

## Build

First, install [cargo component](https://github.com/bytecodealliance/cargo-component):

```
cargo install cargo-component@0.11.0
```

Then execute the following command to compile it into a WASM program:

```
$ cargo component build
```

Or use `--release` option to build it in release mode:

```
$ cargo component build --release
```

## Run

After compilation, you can use [wasmtime](https://github.com/bytecodealliance/wasmtime) to run it:

```
$ wasmtime serve target/wasm32-wasi/debug/http_server.wasm
Serving HTTP on http://0.0.0.0:8080/
```

```
$ curl http://localhost:8080/
Hello, WASI!
$ curl http://localhost:8080/?name=ia
Hello, ia!
```
18 changes: 18 additions & 0 deletions examples/server/src/bindings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Generated by `wit-bindgen` 0.24.0. DO NOT EDIT!
// Options used:

#[cfg(target_arch = "wasm32")]
#[link_section = "component-type:wit-bindgen:0.24.0:http-server:encoded world"]
#[doc(hidden)]
pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 173] = *b"\
\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07,\x01A\x02\x01A\0\x04\
\x01!component:http-server/http-server\x04\0\x0b\x11\x01\0\x0bhttp-server\x03\0\0\
\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-component\x070.202.0\x10wit-bind\
gen-rust\x060.24.0";

#[inline(never)]
#[doc(hidden)]
#[cfg(target_arch = "wasm32")]
pub fn __link_custom_section_describing_imports() {
wit_bindgen_rt::maybe_link_cabi_realloc();
}
15 changes: 15 additions & 0 deletions examples/server/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use waki::{handler, ErrorCode, Request, Response};

#[handler]
fn hello(req: Request) -> Result<Response, ErrorCode> {
let query = req.query();
Response::builder()
.body(
format!(
"Hello, {}!",
query.get("name").unwrap_or(&"WASI".to_string())
)
.as_bytes(),
)
.build()
}
Binary file added examples/server/wasi_snapshot_preview1.proxy.wasm
Binary file not shown.

0 comments on commit e6d932d

Please sign in to comment.