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.

// src/lib.rs
use bindings::exports::wasi::http::incoming_handler::Guest;
use bindings::wasi::http::types::{
Fields, IncomingRequest, OutgoingResponse, ResponseOutparam,
};
struct Component;
impl Guest for Component {
fn handle(_request: IncomingRequest, response_out: ResponseOutparam) {
let headers = Fields::new();
headers
.set("content-type", &[b"application/json".to_vec()])
.unwrap();
let response = OutgoingResponse::new(headers);
response.set_status_code(200).unwrap();
let body = response.body().unwrap();
let stream = body.write().unwrap();
stream
.blocking_write_and_flush(br#"{"service":"acme-api","ok":true}"#)
.unwrap();
drop(stream);
OutgoingResponse::finish(body, None).unwrap();
ResponseOutparam::set(response_out, Ok(response));
}
}
bindings::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.

[project]
name = "acme"
[resource.api]
lane = "rust"
public = 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