Migrate volo-http to WASI
Cargo.toml
tokio_wasi = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
http = { version = "0.2" }
volo-http-wasi = { git = "ssh://[email protected]/lz1998/volo-http-wasi.git", branch = "main"}
src/main.rs
use std::net::SocketAddr;
use http::{Method, StatusCode, Uri};
use serde::{Deserialize, Serialize};
use volo_http_wasi::{
handler::HandlerService,
request::Json,
route::{Route, Router, Server},
};
#[tokio::main(flavor = "current_thread")]
async fn main() {
Router::new()
.route(
"/ping",
Route::builder()
.post(HandlerService::new(json))
.get(HandlerService::new(ping))
.build(),
)
.serve(SocketAddr::from(([127, 0, 0, 1], 3000)))
.await
.unwrap();
}
async fn ping(u: Uri, m: Method) -> &'static str {
println!("{m:?} {u:?}");
"pong"
}
#[derive(Serialize, Deserialize, Debug)]
struct Person {
name: String,
age: u8,
phones: Vec<String>,
}
async fn json(Json(mut req): Json<Person>) -> Result<Json<Person>, (StatusCode, &'static str)> {
if !req.phones.is_empty() {
println!("{req:?}");
req.name.push('a');
req.phones.push(String::from("123"));
Ok(Json(req))
} else {
Err((StatusCode::BAD_REQUEST, "phones is empty"))
}
}
- Install WasmEdge
rustup target add wasm32-wasi
- Compile:
cargo build --target wasm32-wasi --release
- Run:
wasmedge ./target/wasm32-wasi/release/server.wasm
- Update Docker to the latest version, and open the following options in
Settings
-Features in development
-
Use containerd for pulling and storing images
-
Enable Wasm
-
- Build docker image
cargo build --target wasm32-wasi --release docker build -t wasm-http-server .
- Run docker image
docker run --rm -d -p 3000:3000 \ --name=wasm-http-server \ --runtime=io.containerd.wasmedge.v1 \ wasm-http-server
curl http://localhost:3000/ping
curl --location 'http://localhost:3000/ping' \
--header 'Content-Type: application/json' \
--data '{
"name": "a",
"age": 1,
"phones": [
"a"
]
}'