Menu
Public repository / 91bd2a37654909c5a3aef6ddd614991bd378ccb8
AkurAI-Framework / site/content/docs/forms.md
Latest change 0ebc2057fd9a65182855334c219522ae944ad484 - docs: /docs guides for routing, forms, storage, middleware, SEO, styling + dev server by Ólafur Búi Ólafsson
# Forms & actions
The server reads request bodies and handles plain HTML form submissions — no
client framework required. A form works with JavaScript disabled; that's the
progressive-enhancement baseline the framework is built on.
## Reading the body
Every handler receives the parsed request. The body is read from the socket
using `Content-Length` (capped at 8 MiB) and exposed on the request:
- `req.body` — the raw bytes (`Vec<u8>`).
- `req.body_str()` — the body as lossy UTF-8 text.
- `req.content_length()` — the declared length, if any.
`GET` requests and any request without a `Content-Length` have an empty body.
## Parsing a form
The `akurai_http::form` module parses `application/x-www-form-urlencoded` — what
a browser submits for `<form method="post">` — with percent-decoding and `+`
meaning space:
```rust
let pairs = akurai_http::form::parse_urlencoded(&req.body_str());
let name = akurai_http::form::field(&pairs, "name").unwrap_or("");
```
## The Post/Redirect/Get pattern
A submission should validate, act, and then **redirect** to a GET, so a browser
refresh never resubmits:
```rust
if name.is_empty() {
return render_form_with_error(...); // re-render, keep what they typed
}
store.append(&record)?; // do the work
Response::new(303).with_header("Location", "/guestbook") // redirect back
```
## Worked example: the guestbook
The live `/guestbook` is the full pattern end to end:
- `GET /guestbook` lists entries.
- `POST /guestbook` validates that name and message are present, stores the
entry (durably — see [Storage](/docs/storage)), and 303-redirects to the list.
- On a validation error it re-renders the form with the message and the values
already typed.
## Safety
User input rendered with `{{ }}` is HTML-escaped by the template engine, so a
submitted `<script>` shows as text, not markup. Use `{{{ }}}` only for content
you trust to be safe HTML.