Skip to content

Commit d007e92

Browse files
authored
Create new section on how to use HTTP in components (#336)
Includes a Rust guide on creating an HTTP Wasm component with wstd.
1 parent 501efbf commit d007e92

3 files changed

Lines changed: 136 additions & 0 deletions

File tree

component-model/src/SUMMARY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
- [Other languages](./language-support/creating-runnable-components/other-languages.md)
3838
- [Using WIT resources](./using-wit-resources.md)
3939
- [Rust](./language-support/using-wit-resources/rust.md)
40+
- [Using HTTP in components](./using-http-in-components.md)
41+
- [Rust](./language-support/using-http-in-components/rust.md)
4042
- [Running Components](./running-components.md)
4143
- [Wasmtime](./running-components/wasmtime.md)
4244
- [jco](./running-components/jco.md)
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Rust
2+
3+
## 1. Setup
4+
5+
Add the `wasm32-wasip2` target to the Rust toolchain.
6+
7+
```rust
8+
rustup target add wasm32-wasip2
9+
```
10+
11+
12+
Install [`wasmtime`][wasmtime]. The Wasmtime CLI has a built-in HTTP server that supports serving WebAssembly HTTP components.
13+
14+
```console
15+
curl https://wasmtime.dev/install.sh -sSf | bash
16+
```
17+
18+
[wasmtime]: https://github.com/bytecodealliance/wasmtime#installation
19+
20+
## 2. Creating a Rust WebAssemly project
21+
22+
Create a new Rust project with `cargo new`:
23+
24+
25+
```console
26+
cargo new wasm-http-hello-world
27+
cd wasm-http-hello-world
28+
```
29+
30+
31+
Add [`wstd`][wstd], a Rust async standard library for Wasm components as a dependency with `cargo add`:
32+
```console
33+
cargo add wstd
34+
```
35+
`wstd` provides idiomatic Rust bindings for WASI standard interfaces [(`wasi:http`)](https://github.com/WebAssembly/WASI/tree/main/proposals/http) to increase ease-of-use for Rust WebAssembly components. Since we are using `wstd`, we will not need to add WIT files or depend on [`wit-bindgen`](https://crates.io/crates/wit-bindgen) directly.
36+
37+
38+
> [!NOTE]
39+
40+
> It is possible to build an HTTP component in Rust without `wstd`. Building a HTTP component without `wstd` would require defining the [`wasi:http`](https://github.com/WebAssembly/WASI/tree/main/proposals/http) imports/exports of the component in WIT, fetching WIT dependencies with `wkg` and generating the Rust bindings with `wit-bindgen`.
41+
>
42+
> Both approaches are valid, but `wstd` offers superior developer experience, so we opt to use it here.
43+
>
44+
> `wstd` and `wit-bindgen` are not mutually exclusive and can co-exist in the same project.
45+
46+
[wstd]: https://docs.rs/wstd/latest/wstd/index.html
47+
48+
## 3. Writing the HTTP handler
49+
50+
We will implement the HTTP handler in `src/main.rs`. The file should look like the following:
51+
```rust
52+
use wstd::http::{Body, Request, Response, Result, StatusCode};
53+
54+
// WASI HTTP server components don't use a traditional `main` function.
55+
// They export a function named `handle` which takes a `Request`
56+
// argument, and which may be called multiple times on the same
57+
// instance. To let users write a familiar `fn main` in a file
58+
// named src/main.rs, wstd provides this `wstd::http_server` macro, which
59+
// transforms the user's `fn main` into the appropriate `handle` function.
60+
#[wstd::http_server]
61+
async fn main(req: Request<Body>) -> Result<Response<Body>> {
62+
match req.uri().path() {
63+
"/" => home(req).await,
64+
_ => not_found(req).await,
65+
}
66+
}
67+
68+
async fn home(_req: Request<Body>) -> Result<Response<Body>> {
69+
Ok(Response::new("Hello, world!\n".into()))
70+
}
71+
72+
async fn not_found(_req: Request<Body>) -> Result<Response<Body>> {
73+
Ok(Response::builder()
74+
.status(StatusCode::NOT_FOUND)
75+
.body(().into())
76+
.expect("builder succeeds"))
77+
}
78+
```
79+
80+
## 4. Compiling and running the component
81+
82+
83+
Build the component:
84+
85+
86+
```console
87+
cargo build --release --target wasm32-wasip2
88+
```
89+
90+
91+
The `.wasm` binary for the component can be found at `target/wasm32-wasip2/release/wasm-http-hello-world.wasm`.
92+
93+
94+
To run the component, we can use [`wasmtime`](https://github.com/bytecodealliance/wasmtime/), a reference implementation host that supports the Component Model.
95+
96+
In particular, we can use `wasmtime serve` subcommand, which will spin-up an HTTP server at `http://localhost:8080` which will use our component to fulfill web requests. `wasmtime` creates a *fresh* instance of the component every time a request is served.
97+
98+
99+
```console
100+
wasmtime serve -Scli -Shttp target/wasm32-wasip2/release/wasm-http-hello-world.wasm
101+
```
102+
103+
104+
You can test it with `curl -i localhost:8080`
105+
106+
107+
```console
108+
HTTP/1.1 200 OK
109+
transfer-encoding: chunked
110+
date: Mon, 13 Apr 2026 23:22:20 GMT
111+
112+
Hello, world!
113+
```
114+
115+
With this, we have successfully built and run a basic WebAssembly HTTP component with Rust 🎉
116+
117+
## 5. Going further
118+
119+
Explore more examples of projects that use `wstd`:
120+
121+
- [An example `wasi:http` server component](https://github.com/bytecodealliance/sample-wasi-http-rust)
122+
- [Various examples of using wstd](https://github.com/bytecodealliance/wstd/tree/main/examples)
123+
- [Examples of using wstd with Axum](https://github.com/bytecodealliance/wstd/tree/main/axum/examples)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Using HTTP in components
2+
3+
This section contains language-specific guides on how to serve a simple HTTP service with a WebAssembly component.
4+
5+
## Languages
6+
7+
This guide is implemented for various languages:
8+
9+
| Language |
10+
|--------------------------------------------------------|
11+
| [Rust](./language-support/using-http-in-components/rust.md) |

0 commit comments

Comments
 (0)