writeonce/docs/examples/web-app
shoney.arickathil 3d33b7bf58 feat(framework): v1 polish — helpers, 405+Allow, HEAD, Logging, set_header
- App.get/post/put/delete_(pattern, take h: Handler) — the take-interface
  shape probe-proven release + ASan before landing; retires plan-16
  deviation 1; delete_ because delete is the query keyword
- dispatch matches path-first: wrong method on a known path answers 405
  with Allow in registration order; unknown path stays 404
- HEAD routed as GET, body suppressed, Content-Length names the body a
  GET would carry (serialize gains head_only)
- Logging middleware (request line to stderr) ships in router/
- set_header(mut r, name, value) — the builder escape hatch
- web-app registers through the helpers (dogfood); README documents all
- gate grows 14 -> 16: 405+Allow, HEAD-vs-GET content-length equality
- all gates green: web-app 16/0, woc-test 540/0, oop-e2e 89/0,
  deps-accept 8/0, log-watcher 7/0, employee 8/0
- board/story: iteration 17 parked (spec+plan ready on library-internal),
  16 carries the v1-polish landing, order list updated

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 03:04:57 +02:00
..
main.wo feat(framework): v1 polish — helpers, 405+Allow, HEAD, Logging, set_header 2026-08-20 03:04:57 +02:00
README.md feat(examples): framework skeleton + web-app scaffold (iter 16 Task 1) 2026-08-19 19:43:19 +02:00
types.wo feat: web-app storefront + dep-relative use resolution (iter 16 Task 4) 2026-08-19 19:56:18 +02:00
wo.toml feat: web-app storefront + dep-relative use resolution (iter 16 Task 4) 2026-08-19 19:56:18 +02:00

web-app — the storefront sample

A small store: Product/Order as @table classes, JSON routes, one auth middleware — built on writeonce-framework, which it imports through [deps] (iteration 15). This app is iteration 16's acceptance workload: just web-app runs the whole chain — fetch → lock → build → serve → curl matrix → restart persistence → SIGTERM.

Routes

Route What
GET /products list (JSON array)
GET /products/:id one product or 404
POST /products create from a JSON body (name, price, stock); 400 on malformed JSON; 409 on a duplicate name (@unique)
POST /orders create (product, qty); FK checked
DELETE /products/:id 409 while orders reference it (FK restrict), 200 after

Every request needs authorization: Bearer <token> (the auth middleware); the token comes from the WA_TOKEN env var.

Run

woc .                       # fetches deps, builds target/web-app
WA_TOKEN=secret WO_DATA=./data ./target/web-app 8080

TLS / HTTP2

None here, deliberately: deploy behind nginx/caddy — the proxy terminates TLS+ALPN and speaks h2 to browsers while this backend serves HTTP/1.1 keep-alive. Sketch:

server {
  listen 443 ssl;
  http2 on;
  location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
  }
}