HTTP mounting
Use case: versioned API under /api/v1
Section titled “Use case: versioned API under /api/v1”Sub-routers group related routes. Mount attaches them under a URL prefix without repeating the prefix on every route.
Example source: vow-examples/vow-web-server/mounted_api.vow
import lib.appimport lib.requestimport lib.responseimport lib.routerimport lib.serve
fn user_by_id(req: request.Request) -> response.Response { let id = request.param(req, "id"); let body = "{\"id\":\"" + id + "\"}"; return response.json(body);}
fn api_health(_req: request.Request) -> response.Response { return response.json("{\"api\":\"v1\"}");}
fn main(caps: Caps) -> int { let sub = router.router_get( router.router_get(router.router_new(), "/health", api_health), "/users/:id", user_by_id ); let a = app.mount(app.app(), "/api/v1", sub); return match caps.net { Some(cap) => serve.listen(a, cap, 8787), None => 0 - 1, };}./vow run vow-examples/vow-web-server/mounted_api.vow -- --grant net:
curl -sf http://127.0.0.1:8787/api/v1/healthcurl -sf http://127.0.0.1:8787/api/v1/users/42Key concepts
Section titled “Key concepts”| URL | Handler | Notes |
|---|---|---|
GET /api/v1/health |
api_health |
Sub-router route |
GET /api/v1/users/:id |
user_by_id |
:id → param(req, "id") |
GET /api/v2/health |
— | 404 (no mount) |
Mount strips the prefix before dispatching to the child router — child routes register as /health, /users/:id, not /api/v1/health.
Unit test
Section titled “Unit test”assert app.try_handle(a, "GET /api/v1/users/99") == 200;assert app.try_handle(a, "GET /api/v1/nope") == 404;