Build Applications

HTTP Service

Build, inspect, and deploy a checked HTTP/1.1 handler within the generated service host.

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:

BASH
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 --locked

The entry module exports exactly one handler with this shape:

TOPAZ
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:

BASH
topaz dev --root hello-service --port 8080
curl --fail-with-body http://127.0.0.1:8080/health

topaz 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 fixed service settings under [service]:

TOML
[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 fail during package loading. Each request receives a fresh runtime context and module graph. Requests use separate Topaz heaps. Queue saturation, oversized inputs, handler deadlines, and invalid responses produce the declared host outcomes.

Build and inspect the product

BASH
topaz build --root hello-service --locked --release --out-dir hello-service-product
cd hello-service-product
./target/release/program --print-config
./target/release/program

On Windows, run target\release\program.exe. The product tree is:

Output
hello-service-product/
├── GENERATED-OUTPUT-NOTICE.txt
├── LICENSE
├── NOTICE
├── THIRD-PARTY-NOTICES.txt
├── target
│   └── release
│       └── program[.exe]
├── topaz-artifact.json
└── topaz-service-config.json

program[.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:

BASH
./target/release/program --bind 0.0.0.0 --port 8080

Use 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 the declared HTTP errors where framing permits a response.
  • A full handler queue returns 503. A handler deadline returns 504.
  • A runtime fault or invalid application response returns a generic 500 without exposing source paths, request content, or Topaz fault text.
  • Responses and host logs share a request ID. Logs omit targets, bodies, and header values.
  • SIGINT and, on Unix, SIGTERM stop admission and drain existing work until shutdown_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.