Documentation
Language Guide
Rust
Tutorials
WASIX with Axum

WASIX with Axum

This is a sample project that shows how to use Axum with the WASIX toolchain.

Prerequisites

⚠️

Please check that you have the latest version of wasmer runtime as this tutorial depends on version 4.1.1 or higher.

The project requires the following tools to be installed on your system:

Start a new project

$ cargo new --bin wasix-axum
     Created binary (application) `wasix-axum` package

Your wasix-axum directory structure should look like this:

Add dependencies

$ cd wasix-axum
$ cargo add axum --features tokio
$ cargo add tokio --features full

Now your Cargo.toml should look like this:

Cargo.toml
[package]
name = "wasix-axum"
version = "0.1.0"
edition = "2021"
 
[dependencies]
axum = { version = "0.6.18", features = ["tokio"] }
tokio = { version = "1.28.1", features = ["full"] }

Writing the Application

Basic Application Setup

Now, let's stub out a basic get route that returns a string using a handler function.

src/main.rs
use axum::{routing::get, Router};
use std::net::SocketAddr;
 
#[tokio::main]
async fn main() {
    // Building our application with a single Route
    let app = Router::new().route("/", get(handler));
 
    // Run the server with hyper on http://127.0.0.1:3000
    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .await
        .unwrap();
}
 
async fn handler() -> &'static str {
    "Hello, Axum ❤️ WASIX!"
}
 

Running the Application

Run the application with the cargo:

$ cargo run
   Compiling wasix-axum v0.1.0 (/wasix-axum)
    Finished dev [unoptimized + debuginfo] target(s) in 1.41s
     Running `target/debug/wasix-axum`

Now in a separate terminal, you can use curl to make a request to the server:

$ curl http://127.0.0.1:3000
Hello, Axum ❤️ WASIX!%

Hmm, but let's see does it work with wasix ? Let's try to build it with wasix:

$ cargo wasix build
...
    ::: .cargo/registry/src/index.crates.io/socket2-0.4.9/src/lib.rs:104:16
     |
104  |             fn from(socket: $from) -> $for {
     |                ---- implicitly returns "()" as its body has no tail or `return` expression
 
Some errors have detailed explanations: E0061, E0308, E0412, E0422, E0425, E0432, E0433, E0583, E0618.
For more information about an error, try `rustc --explain E0061`.
error: could not compile `socket2` (lib) due to 202 previous errors
warning: build failed, waiting for other jobs to finish..
...

Oh no, it doesn't work. But why ?

Compiling with WASIX

ℹ️

For making certain features such as networking, sockets, threading, etc. work with wasix we need patch dependencies for some crates that use those features.

Let's add the following patch to our Cargo.toml:

Cargo.toml
[package]
name = "wasix-axum"
version = "0.1.0"
edition = "2021"
 
[dependencies]
axum = { version = "=0.6.9", features = ["tokio"] } # ← Updated Line
tokio = { version = "=1.24.2", default-features = false, features = ["full"] } # ← Updated Line
parking_lot = { version = "=0.12.1", features = ["nightly"] } # ← Added Line
 
[patch.crates-io]
socket2 = { git = "https://github.com/wasix-org/socket2.git", branch = "v0.4.9" } # ← Added Line
libc = { git = "https://github.com/wasix-org/libc.git" } # ← Added Line
tokio = { git = "https://github.com/wasix-org/tokio.git", branch = "wasix-1.24.2" } # ← Added Line
ℹ️

As you can see above the parking_lot crate works out of the box 🚀 with wasix. It just needs the nightly feature to be enabled.

🚧

We need to pin and replace some dependencies to achieve wasix compatibility. So, currently supported axum version is 0.6.9 and tokio version is 1.24.2.

Now, let's try to build it with wasix again:

$ cargo wasix build
    Blocking waiting for file lock on package cache
    Updating crates.io index
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
   Compiling tokio v1.24.2 (https://github.com/wasix-org/tokio.git?branch=wasix-1.24.2#8ba16a72)
   Compiling tower v0.4.13
   Compiling hyper v0.14.26
   Compiling tower-http v0.4.0
   Compiling axum v0.6.9
   Compiling wasix-axum v0.1.0 (/wasix-axum)
    Finished dev [unoptimized + debuginfo] target(s) in 14.63s
info: Post-processing WebAssembly files

Yay, it builds! Now, let's try to run it:

🚨

It could happen that the above command might fail for you, this is because of dependencies not resolving correctly. You can easily fix this by running cargo update and then running cargo wasix build again.

$ cargo wasix run
    Finished dev [unoptimized + debuginfo] target(s) in 0.23s
     Running `/Users/xorcist/.cargo/bin/cargo-wasix target/wasm32-wasmer-wasi/debug/wasix-axum.wasm`
info: Post-processing WebAssembly files
     Running `target/wasm32-wasmer-wasi/debug/wasix-axum.wasm`
thread 'main' panicked at 'error binding to 127.0.0.1:3000: error creating server listener: Not supported (os error 58)', .cargo/registry/src/index.crates.io-/hyper-0.14.26/src/server/server.rs:79:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: failed to run `target/wasm32-wasmer-wasi/debug/wasix-axum.wasm`
╰─▶ 1: RuntimeError: unreachable
error: failed to execute "wasmer" "--enable-threads" "--" "target/wasm32-wasmer-wasi/debug/wasix-axum.wasm"
    status: exit status: 134
🚧

Currently, we need to run it using wasmer run. See the issue (opens in a new tab)

Let's try to run it with wasmer:

$ wasmer run target/wasm32-wasmer-wasi/debug/wasix-axum.wasm --net --enable-threads

Let's go through the flags we used above:

  1. --net - This flag enables networking support for wasm files.
  2. --enable-threads - This flag enables threading support for wasm files.

Now in a separate terminal, you can use curl to make a request to the server:

$ curl http://localhost:3000
Hello, Axum ❤️ WASIX!

Yay, it works! 🎉

ℹ️

You can also deploy your application to the edge. Checkout this tutorial (opens in a new tab) for deploying your wasix-axum server to wasmer edge.

Conclusion

In this tutorial, we learned:

  • How to build a simple web server using axum and compile it with wasix.
  • How to patch dependencies add WASIX support until changes are adopted upstream.
  • How to run wasix based .wasm files with Wasmer.
  • How to enable networking and threading support for wasm files.
wasix-rust-examples/wasix-axum