-- web-app — the storefront: writeonce-framework (via [deps]) + @table -- persistence. Every handler is a class satisfying Handler; the auth gate is -- a Middleware; the data layer is the language's own database — no ORM, no -- separate process, one binary. use env use json use framework use framework/http use framework/router -- decode target for POST /products, encode shape for every product answer typedef ProductView = { name: Text, price: Float, stock: Int } typedef NewOrder = { product: Text, qty: Int } fn view_json(name: Text, price: Float, stock: Int) -> Text { return json.encode(ProductView { name: name, price: price, stock: stock }); } class ListProducts { pad: Int fn handle(req: Req) -> Resp { let body = "["; let first = true; for p in from x in Product order by x.name select x { if first == false { body = body .. ","; } first = false; body = body .. view_json(p.name, p.price, p.stock); } return ok_json(body .. "]"); } } class ShowProduct { pad: Int fn handle(req: Req) -> Resp { let name = req.params["name"]; if name == nil { return bad_request("no name"); } let hits = from p in Product where p.name == name take 1 select p; if len(hits) == 0 { return not_found(); } let p = hits[0]; return ok_json(view_json(p.name, p.price, p.stock)); } } -- Accepts THREE bodies: multipart/form-data (curl -F), a form post -- (application/x-www-form-urlencoded), and JSON — same insert either way. fn create_product(name: Text, price: Float, stock: Int) -> Resp { let made = try insert Product { name: name, price: price, stock: stock } catch (e) nil; if made == nil { return conflict("product name already exists"); } return created_json(view_json(name, price, stock)); } class CreateProduct { pad: Int fn handle(req: Req) -> Resp { if media_type(req) == "multipart/form-data" { let ps = multipart_parts(req); if ps == nil { return bad_request("unreadable multipart body"); } let name = part_named(ps, "name"); if name == nil { return bad_request("multipart needs name, price, stock"); } let pstr = part_named(ps, "price"); if pstr == nil { return bad_request("multipart needs name, price, stock"); } let sstr = part_named(ps, "stock"); if sstr == nil { return bad_request("multipart needs name, price, stock"); } -- parse_float answers NaN for unparseable input rather than a ?Float: -- "not a number" is already a Float value, and NaN != NaN is the test let price = parse_float(pstr); if price != price { return bad_request("price must be a number"); } let stock = parse_int(sstr); if stock == nil { return bad_request("stock must be a number"); } return create_product(name, price, stock); } if media_type(req) == "application/x-www-form-urlencoded" { let f = form_values(req); if f == nil { return bad_request("unreadable form body"); } let name = f["name"]; if name == nil { return bad_request("form needs name, price, stock"); } let ps = f["price"]; if ps == nil { return bad_request("form needs name, price, stock"); } let ss = f["stock"]; if ss == nil { return bad_request("form needs name, price, stock"); } let price = parse_float(ps); if price != price { return bad_request("price must be a number"); } let stock = parse_int(ss); if stock == nil { return bad_request("stock must be a number"); } return create_product(name, price, stock); } let v = json.decode(req.body) as ProductView; if v == nil { return bad_request("body must be {name, price, stock}"); } return create_product(v.name, v.price, v.stock); } } class CreateOrder { pad: Int fn handle(req: Req) -> Resp { let v = json.decode(req.body) as NewOrder; if v == nil { return bad_request("body must be {product, qty}"); } if v.qty < 1 { return bad_request("qty must be positive"); } let hits = from p in Product where p.name == v.product take 1 select p; if len(hits) == 0 { return not_found(); } insert Order { product: hits[0], qty: v.qty }; return created_json("{\"ok\":true}"); } } class DeleteProduct { pad: Int fn handle(req: Req) -> Resp { let name = req.params["name"]; if name == nil { return bad_request("no name"); } let hits = from p in Product where p.name == name take 1 select p; if len(hits) == 0 { return not_found(); } let gone = try delete hits[0] catch (e) nil; if gone == nil { return conflict("orders still reference this product"); } return ok_json("{\"deleted\":true}"); } } -- ---- framework v1 slice 2: the storefront exercises the new surface ---- -- wildcard capture: GET /files/*path echoes the rest class EchoPath { pad: Int fn handle(req: Req) -> Resp { let p = req.params["path"]; if p == nil { return ok_text("path="); } return ok_text("path=${p}"); } } -- group middleware writes the request-scoped ctx bag; the handler reads it class StampCtx { pad: Int fn before(mut req: Req) -> ?Resp { req.ctx["via"] = "api-group"; return nil; } } class ApiPing { pad: Int fn handle(req: Req) -> Resp { let via = req.ctx["via"]; if via == nil { return ok_text("pong via="); } return ok_text("pong via=${via}"); } } -- ETag + conditional: same body = same tag; If-None-Match collapses to 304 class EtagProbe { pad: Int fn handle(req: Req) -> Resp { return with_etag(req, ok_json("{\"v\":1}")); } } -- response-side negotiation: JSON or nothing class NegoProbe { pad: Int fn handle(req: Req) -> Resp { if accepts(req, "application/json") == false { let h: map = {}; h["content-type"] = "application/json"; return Resp { status: 406, headers: h, body: "{\"error\":\"json only\"}" }; } return ok_json("{\"ok\":true}"); } } fn main(args: multi Text) -> Int { if len(args) < 1 { print_err("usage: web-app (WA_TOKEN and WO_DATA must be set)"); return 2; } let port = parse_int(args[0]); if port == nil { print_err("web-app: must be a number"); return 2; } let token = env.get("WA_TOKEN"); if token == nil { print_err("web-app: WA_TOKEN is required (the auth middleware's bearer token)"); return 2; } let app = App { middleware: [], routes: [] }; -- v1 slice 2: host gate first (421 before anything runs), CORS preflight -- next, then the framework's Bearer mechanism (constant-time compare, -- principal attached to req.principal for handlers that want "who") app.use_mw(Mw { m: HostAllow { host: "a" } }); app.use_mw(Mw { m: Cors { allow_origin: "*" } }); app.use_mw(Mw { m: BearerAuth { token: token, principal: "api" } }); -- the response half: security headers + the CORS origin stamp on every -- response that leaves dispatch (404/405/401 included) app.use_after(Aw { a: SecurityHeaders { pad: 0 } }); app.use_after(Aw { a: Cors { allow_origin: "*" } }); app.get("/products", ListProducts { pad: 0 }); app.get("/products/:name", ShowProduct { pad: 0 }); app.post("/products", CreateProduct { pad: 0 }); app.post("/orders", CreateOrder { pad: 0 }); app.delete_("/products/:name", DeleteProduct { pad: 0 }); app.get("/files/*path", EchoPath { pad: 0 }); app.get("/etag-probe", EtagProbe { pad: 0 }); app.get("/nego", NegoProbe { pad: 0 }); let g = Group { prefix: "/api" }; g.use_mw(Mw { m: StampCtx { pad: 0 } }); g.get("/ping", ApiPing { pad: 0 }); app.mount(g); return app.serve("127.0.0.1", port); }