Routing
Route registration returns an updated handle — reassign after each get / post / … call.
HTTP methods
Section titled “HTTP methods”| Function | Registers |
|---|---|
get(app, path, h) |
GET |
post(app, path, h) |
POST |
put(app, path, h) |
PUT |
delete(app, path, h) |
DELETE |
patch(app, path, h) |
PATCH |
all(app, path, h) |
GET, POST, PUT, DELETE, PATCH on the same path |
Works on both server() handles and router() handles.
Express → vow-web-server
Section titled “Express → vow-web-server”Express
const app = express();app.get('/echo', (req, res) => res.send('ok'));app.all('/probe', (req, res) => res.send('ok'));vow-web-server
import vws from vow_web_serverimport vow_web_server.requestimport vow_web_server.response
fn any_method(_req: request.Request) -> response.Response { return vws.send("ok");}
fn main(caps: Caps) -> int { let rt = vws.runtime(caps); var app = vws.server(); app = vws.all(app, "/echo", any_method); return vws.serve(app, rt, 8787);}all registers five routes with the same handler — useful for catch-all endpoints or method-agnostic probes.
Path parameters
Section titled “Path parameters”Use :name segments in the path pattern. The matched value is available via request.param(req, "name"):
Express
app.get('/users/:id', (req, res) => { res.json({ id: req.params.id });});vow-web-server
fn user_by_id(req: request.Request) -> response.Response { let id = vws.param(req, "id"); return vws.json("{\"id\":\"" + id + "\"}");}
var app = vws.server();app = vws.get(app, "/users/:id", user_by_id);Query strings use request.query(req, "key") — separate from path params.
Mount (sub-router)
Section titled “Mount (sub-router)”Build a standalone router, attach middleware, register routes, then mount under a prefix:
Express
const api = express.Router();api.get('/health', apiHealth);api.get('/users/:id', userById);app.use('/api/v1', api);vow-web-server
var api = vws.router();api = vws.get(api, "/health", api_health);api = vws.get(api, "/users/:id", user_by_id);app = vws.use_middleware(app, "/api/v1", api);A request to GET /api/v1/users/42 dispatches to user_by_id with param(req, "id") == "42". Middleware registered on the sub-router applies under the mount prefix.
Nested mounts work the same way — mount a router onto another router:
var admin = vws.router();admin = vws.get(admin, "/stats", stats);
var api = vws.router();api = vws.get(api, "/users", list_users);api = vws.use_middleware(api, "/admin", admin);
app = vws.use_middleware(app, "/api/v1", api);// GET /api/v1/admin/stats → statsSee HTTP mounting tutorial and vow-examples/vow-web-server/mounted_api.vow.
404 and 405
Section titled “404 and 405”| Situation | Status | Body |
|---|---|---|
| No route or mount matches the path | 404 | {"error":"not found"} |
| Path matches a route but HTTP method does not | 405 | {"error":"method not allowed"} |
Example: register only GET /health. A POST /health returns 405; GET /nope returns 404.
Unit-test status codes without network I/O:
assert vws.try_handle(app, "GET /health") == 200;assert vws.try_handle(app, "POST /health") == 405;assert vws.try_handle(app, "GET /nope") == 404;Legacy router API
Section titled “Legacy router API”v0.1/v0.2 names remain as deprecated aliases:
| Legacy | v0.3 preferred |
|---|---|
app() |
server() |
router_new() |
router() |
router_get(r, path, h) |
get(r, path, h) on a router handle |
mount(a, prefix, sub) |
use_middleware(a, prefix, router) |
router_try_dispatch(r, raw) |
try_handle(app, raw) |
serve_loop(r, cap, port) |
serve(app, rt, port) |
Prefer the v0.3 handle API for middleware integration and Express-like ergonomics.