Server — Router and Decorators
Zolo's HTTP server runs in the host process (hyper + tokio) and does not terminate:
calling http.serve(port, app) blocks the script and begins serving requests in a loop.
To test it, open another terminal and use curl.
The first approach uses pipe composition: http.router() creates an empty router;
each http.get("/route", handler) call attaches a route and returns the same router,
ready for the next |>:
http.router() |> http.get(...) |> http.serve(port, app).
// Feature: HTTP server — router via pipes
// Syntax: `http.router() |> http.get("/path", handler) |> ...`
// When to use: simple APIs; declarative composition of routes with pipes.
use std::http
// Each handler receives `req` and returns a string, map, or `http.response(...)`.
fn handle_root(_req) {
return "Hello from the Zolo server!"
}
fn handle_health(_req) {
return #{status: "ok"}
}
let app = http.router()
|> http.get("/", handle_root)
|> http.get("/health", handle_health)
// Runs in the foreground on port 3000.
http.serve(3000, app)
// expected when running:
// curl http://localhost:3000/ -> Hello from the Zolo server!
// curl http://localhost:3000/health -> {"status":"ok"}
Requires the Zolo CLI/host — open in the playground or run locally.
The second approach is the decorator style: annotating a fn with @get,
@post, @put or @delete registers the route automatically; http.serve(port)
without an app argument uses the global registry:
@get/@post/@put/@delete — automatic route registration.
// Feature: HTTP server — `@get`/`@post`/`@put`/`@delete` decorators
// Syntax: annotate a `fn` with the route; `http.serve(port)` registers them all.
// When to use: "framework" style, APIs with many routes, ergonomics
// close to Flask/Express, without wiring up a router manually.
use std::http
@get("/")
fn index() {
return "Hello from decorator routes!"
}
@get("/health")
fn health() {
return #{status: "ok"}
}
@post("/echo")
fn echo(req) {
// `req.json()` reads the body as JSON and returns it as a map.
return req.json()
}
@put("/items/:id")
fn update_item(req) {
return #{updated: req.params.id}
}
@delete("/items/:id")
fn delete_item(req) {
return #{deleted: req.params.id}
}
http.serve(3001)
// expected when running:
// curl http://localhost:3001/ -> Hello from decorator routes!
// curl -X POST -d '{"x":1}' http://localhost:3001/echo
// curl -X PUT http://localhost:3001/items/42 -> {"updated":"42"}
// curl -X DELETE http://localhost:3001/items/42 -> {"deleted":"42"}
Requires the Zolo CLI/host — open in the playground or run locally.
Each handler receives req and can return a string (200 text/plain), a map
(200 application/json) or a value built with the response helpers shown later.
See also