Deploy a Rust API

View as Markdown

This tutorial builds a JSON API in Rust as a WebAssembly component and deploys it to Hyjal on the Rust lane. You end with a public HTTPS endpoint that returns JSON, proven with curl.

Time: about ten minutes. You need the hyjal CLI, a logged-in session, and a Rust toolchain with the wasm32-wasip2 target and cargo component.

1. Create the component

Scaffold a new component crate:

$$ cargo component new acme-api --lib
$$ cd acme-api

Implement the wasi:http incoming handler. The component returns a JSON body for every request.

1// src/lib.rs
2use bindings::exports::wasi::http::incoming_handler::Guest;
3use bindings::wasi::http::types::{
4 Fields, IncomingRequest, OutgoingResponse, ResponseOutparam,
5};
6
7struct Component;
8
9impl Guest for Component {
10 fn handle(_request: IncomingRequest, response_out: ResponseOutparam) {
11 let headers = Fields::new();
12 headers
13 .set("content-type", &[b"application/json".to_vec()])
14 .unwrap();
15
16 let response = OutgoingResponse::new(headers);
17 response.set_status_code(200).unwrap();
18
19 let body = response.body().unwrap();
20 let stream = body.write().unwrap();
21 stream
22 .blocking_write_and_flush(br#"{"service":"acme-api","ok":true}"#)
23 .unwrap();
24 drop(stream);
25
26 OutgoingResponse::finish(body, None).unwrap();
27 ResponseOutparam::set(response_out, Ok(response));
28 }
29}
30
31bindings::export!(Component with_types_in bindings);

2. Build locally

Confirm the component compiles to a wasip2 artifact:

$$ cargo component build --release
$ Compiling acme-api v0.1.0
$ Finished release [optimized] target(s) in 3.41s
$ Creating component target/wasm32-wasip2/release/acme_api.wasm

3. Write the manifest

Add a hyjal.toml declaring the api Resource on the Rust lane. Make it public so you can reach it directly.

1[project]
2name = "acme"
3
4[resource.api]
5lane = "rust"
6public = true

The Rust lane runs cargo component build for you at deploy; you do not need to commit the built artifact.

4. Deploy

$$ hyjal deploy
$Building resource api (lane: rust)...
$ cargo component build --release āœ“
$Uploading artifact... digest sha256:a71e3d…09c4
$Applying policy... āœ“
$Flipping route... āœ“
$
$Deployed acme/api
$ https://api--acme.hyjal.cloud

5. Verify with curl

Call the endpoint:

$$ curl https://api--acme.hyjal.cloud
${"service":"acme-api","ok":true}

Inspect the headers to confirm the status and content type:

$$ curl -i https://api--acme.hyjal.cloud
$HTTP/2 200
$content-type: application/json
$
${"service":"acme-api","ok":true}

Each call ran on a fresh Afterburner instance, metered and discarded. No state carries between requests.

6. Watch the requests

$$ hyjal logs -f --resource api
$[15:20:03] GET / 200 2ms
$[15:20:14] GET / 200 1ms

What you built

  • A Rust wasi:http component that returns JSON.
  • A public endpoint at https://api--acme.hyjal.cloud on the Rust lane.
  • A working curl request served instance-per-request.

Next steps