writeonce/reference/rest
shoney.arickathil 9279175f26 scaffold sibling crates, multi-app ecommerce, REST + concurrency docs
- scaffold 14 placeholder crates (app, db, engine, gen, http, logic,
  policy, ql, service, sub, txn, ui, value, wal) — empty Cargo.toml +
  src/lib.rs to receive code phase-by-phase from `rt`
- restructure docs/examples/ecommerce into multi-app layout: apps/admin
  and apps/storefront, with shared/ types/logic/components, per-app
  app.wo + wo.toml, and reusable .htmlx components (layout, money,
  order-row)
- add reference/rest/{blog,ecommerce}.rest — VS Code/JetBrains HTTP
  request files driving the running prototype, including 501/404/405
  expectations for stubbed endpoints
- add docs/plan/09-concurrency-scaleout.md and docs/plan/ui/00-overview.md;
  refine docs/plan/assembly/02-writeonce-stance.md
- refresh templates (about, article, header/footer, home, layout, styles)
  and add static favicon/logo
- add infra/sync.sh and tighten .gitignore for reference/ symlinks
2026-05-04 13:39:58 +02:00
..
blog.rest scaffold sibling crates, multi-app ecommerce, REST + concurrency docs 2026-05-04 13:39:58 +02:00
ecommerce.rest scaffold sibling crates, multi-app ecommerce, REST + concurrency docs 2026-05-04 13:39:58 +02:00
README.md Pivot to the .wo language runtime: design docs, phase plans 2026-04-21 02:48:45 +02:00

reference/rest/ — HTTP test files for the .wo runtime

.rest (or .http) is the plain-text HTTP-request format supported by the two main editor HTTP clients:

  • VS Code — install REST Client (humao.rest-client) and click "Send Request" above any block.
  • JetBrains IDEs (IntelliJ, WebStorm, RustRover, Goland) — built-in HTTP Client recognises .rest and .http natively.

Both clients understand:

  • ### ... block separators
  • @var = value document-level variables referenced as {{var}}
  • # @name foo on a request, whose response fields are later reachable as {{foo.response.body.id}} — useful for threading auto-generated ids from create responses into later get/patch/delete calls

Files

File Against What it exercises
blog.rest docs/examples/blog/ Full CRUD on Article/Comment, read-only on Author/Tag (matches the sample's expose lists). End-to-end flow: create article → list → get by id → PATCH title → PATCH embedded doc → DELETE draft → verify final state.
ecommerce.rest docs/examples/ecommerce/ What Stage 2 currently serves for the ecommerce sample: read-only Product/Order/Customer lists, 405s for non-exposed create endpoints, 501s for Stage 3 stubs. Documents the shape of Stage 3/4 endpoints (fn checkout, LIVE subscribe, /me) even though they're not wired yet.

Running

# one terminal — start the runtime
cargo run --bin wo -- run docs/examples/blog
#    [wo] listening on http://127.0.0.1:8080

# another terminal — or just open the .rest file in VS Code/JetBrains and click

Override the port via WO_LISTEN:

WO_LISTEN=127.0.0.1:9000 cargo run --bin wo -- run docs/examples/blog

…and update the @host line at the top of the .rest file to match.

Without an editor (just curl)

Each .rest block maps directly to curl. Some examples:

# Runtime info
curl http://127.0.0.1:8080/

# List
curl http://127.0.0.1:8080/api/articles

# Create — server assigns `id` automatically
curl -X POST http://127.0.0.1:8080/api/articles \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "hello-writeonce",
    "title": "Hello, writeonce",
    "author": 1,
    "published": true,
    "meta": { "excerpt": "first post", "body_md": "# hi" }
  }'

# Get by id
curl http://127.0.0.1:8080/api/articles/1

# Partial update
curl -X PATCH http://127.0.0.1:8080/api/articles/1 \
  -H "Content-Type: application/json" \
  -d '{ "title": "Updated" }'

# Delete
curl -X DELETE http://127.0.0.1:8080/api/articles/1    # 204 on success

# Stage 3 stub
curl -i http://127.0.0.1:8080/api/articles/live        # 501 Not Implemented

For a scripted smoke run against the blog sample, the top-to-bottom curl sequence that exactly mirrors blog.rest is in docs/examples/blog/README.md.

Expected-status cheat sheet

Every block in the .rest files ends its description with the expected HTTP status. Quick legend:

Status Meaning in this prototype
200 OK — list / get / update succeeded
201 Created — new row, id in the response body
204 No Content — delete succeeded
400 Bad JSON body
404 No such row, OR no method at all is attached to the path (e.g. /api/customers when the service rest block doesn't expose any collection-root op)
405 Method not allowed — the path is registered for a different method (e.g. POST against /api/products when only list is exposed, so GET is attached but POST isn't)
501 Not Implemented — Stage 3+ feature (LIVE subscriptions, /me, transactional fns)

A 405 is a feature of the sample — it confirms the expose list in the .wo file is being honoured. A 501 is a Stage marker — the runtime acknowledges the shape but hasn't wired the handler yet.