HTTP & HTTPS Upstreams
Declare an upstream to call an external REST API with typed requests and responses — pure Zig (std.http.Client + TLS). Calls are fallible (T!): try propagates a failure as an error response, or else handles it.
upstream backend {
base env("BACKEND_URL") # env() reads an environment variable
header "Accept" "application/json"
call getUser(id: int) GET "/users/{id}" -> User
call listUsers() GET "/users" -> [User]
}
route GET "/proxy/:id" (id: int) -> User {
respond try backend.getUser(id) # try -> auto 502 on failure
}
route GET "/safe/:id" (id: int) -> User {
let u = backend.getUser(id) else e { # else -> handle it
status 502
respond "upstream down: {e.message}\n"
}
respond u
}basesets the base URL; a block-levelheader "Name" "value"adds a default header to every call.- Path templates interpolate the call's typed params (
"/users/{id}"). - A
POST/PUTcall with a record or list parameter sends it as a JSON body. - The built-in
Error { status: int, message: string }is whatelsebinds.
Per-call headers. A call can add its own header "Name" <value> clauses whose values interpolate the call's params — so a request-specific header (auth token, correlation id) is forwarded to the upstream:
upstream api {
base "https://api.example.com"
call getUser(id: int, token: string)
GET "/users/{id}"
header "authorization" "Bearer {token}" # forwarded per call
-> User
}
route GET "/me" (auth: string) -> User {
respond try api.getUser(1, auth) # pass the request's token through
}Weld also injects a W3C traceparent automatically for distributed tracing.
HTTPS
An https:// base does a real TLS handshake and verifies the server certificate against the system CA bundle — no configuration needed. See examples/httpsapi.weld, which calls a public JSON API over HTTPS.
TIP
HTTPS upstreams use HTTP/1.1 over TLS, which needs no ALPN, so they work today. This is distinct from native gRPC-over-TLS, which is blocked at the std layer until ALPN lands — see gRPC.