Choose http-service when a checked Topaz function receives an HttpRequest and returns an HttpResponse. The generated native host owns the listener, HTTP/1.1 framing, finite request budgets, overload responses, logging, and shutdown.
This is not a general web server framework. It does not grant outbound networking, raw sockets, ambient environment access, shared mutable Topaz state, TLS, HTTP/2, WebSockets, or sessions. Place a standard reverse proxy in front of the process for public TLS and Internet-edge policy. Treat this explicit Capability boundary as part of the product design.
Complete First Application first. Building the service requires a Rust toolchain for the target deployment platform.
Create, lock, and test
The scaffold supplies the package manifest, service defaults, and a concrete handler:
topaz init --target http-service --root hello-service
topaz lock --root hello-service
topaz fmt --check --root hello-service
topaz check --root hello-service --locked
topaz test --root hello-service --lockedThe entry module exports exactly one handler with this shape:
import std.http { HttpRequest, HttpResponse, text }
export function handle(req: HttpRequest) -> HttpResponse {
if req.method == "GET" && req.url.path() == "/health" {
return text(200, "ok")
}
text(404, "not found")
}The checker rejects missing, generic, variadic, defaulted, or differently typed handlers before the listener can start.
Develop through loopback
Run the generated service on loopback and request its health route:
topaz dev --root hello-service --port 8080
curl --fail-with-body http://127.0.0.1:8080/healthtopaz dev forces the bind address to 127.0.0.1, rebuilds the managed service, and forwards interruption signals to it. If port 8080 is occupied, choose another loopback port with --port.
Keep finite service budgets
The scaffold records bounded defaults under [service]:
[service]
bind = "127.0.0.1"
port = 8080
workers = 1
max_connections = 64
queue_capacity = 32
max_target_bytes = 8192
max_header_bytes = 16384
max_headers = 64
max_body_bytes = 1048576
header_timeout_ms = 5000
body_timeout_ms = 5000
handler_timeout_ms = 1000
shutdown_grace_ms = 5000
log_format = "text"Unknown keys and out-of-range values trigger failures during package loading. Each request receives a fresh runtime context and module graph. Requests do not share a Topaz heap. Queue saturation, oversized inputs, handler deadlines, and invalid responses become bounded host outcomes rather than unbounded work.
Build and inspect the product
topaz build --root hello-service --locked --release --out-dir hello-service-product
cd hello-service-product
./target/release/program --print-config
./target/release/programOn Windows, run target\release\program.exe. The product tree is:
hello-service-product/
├── GENERATED-OUTPUT-NOTICE.txt
├── LICENSE
├── NOTICE
├── THIRD-PARTY-NOTICES.txt
├── target
│ └── release
│ └── program[.exe]
├── topaz-artifact.json
└── topaz-service-config.jsonprogram[.exe] denotes program on Unix and program.exe on Windows. --print-config validates and prints effective settings without opening a listener. The managed JSON file records embedded defaults. Runtime overrides require explicit command-line flags. An explicit non-loopback bind is configured as follows:
./target/release/program --bind 0.0.0.0 --port 8080Use that flag only behind the intended network boundary. The manifest itself may specify only a loopback address.
Observable failures
- Oversized bodies, targets, or header sets produce bounded HTTP errors where framing permits a response.
- A full handler queue returns
503. A handler deadline returns504. - A runtime fault or invalid application response returns a generic
500without exposing source paths, request content, or Topaz fault text. - Responses and host logs share a request ID. Logs omit targets, bodies, and header values.
SIGINTand, on Unix,SIGTERMstop admission and drain existing work untilshutdown_grace_ms.
If check or test fails, resolve the Topaz diagnostic and repeat the command. If a build detects a modified managed file or another target in the output directory, retain that directory for inspection and choose a new empty --out-dir.
Source-free deployment
Copy the complete hello-service-product/ directory so the executable, configuration record, integrity manifest, licenses, and notices stay together. The copied product requires neither package source files, the Topaz CLI, a registry, nor the temporary Cargo workspace. Run it under a process supervisor, retain the generated budgets, and terminate public TLS at a reverse proxy.