5: Routing

Routing in Phlo maps a space-separated path + HTTP method to a target (usually a method). Routes from all .phlo files are collected; the router is activated with app::route().

5.1: Basic form

route [async|both] [GET|POST|PUT|DELETE|PATCH] pad [pad2 ...] => target

Example:

route GET home => $this->main
method main => view($this->home)

5.2: sync / async / both

Keyword Behavior
(omitted) Sync only (regular HTTP)
async Async only (requests from a Phlo frontend)
both Sync and async allowed
route both GET data => $this->loadData
route async POST items save => $this->saveItems

5.3: Variables

Phlo parses every path segment. Segments that start with $ are variables with extra capabilities:

4.3.1 Required (passed to the target)

route GET user $id => $this->showUser($id)
method showUser($id) => view($this->profile)

4.3.2 Optional presence with ?boolean

route GET search $full? => $this->search($full)

4.3.3 Rest (variable length) with =*

route GET file $path=* => $this->serveFile($path)

4.3.4 Default value with =

route GET page $slug=home => $this->page($slug)

4.3.5 Length requirement with .N

route GET code $pin.6 => $this->enter($pin)

4.3.6 Value lists with :a,b,c

route GET report $range:daily,weekly,monthly => $this->report($range)

You can combine these forms. Examples:

Enum with a required id:

route GET export $fmt:csv,json $id => $this->export($fmt, $id)

Enum with a default:

route GET theme $name:light,dark=light => $this->theme($name)

5.4: Payload check with `@`

You specify exact body keys with a single @ and a comma-separated list. The router compares this 1-to-1 with the keys from %payload (exact set; order as supplied by the engine).

route POST user @name,email => $this->createUser

method createUser => dx(%payload->name, %payload->email)

Body keys are not bound as method parameters; you read them via %payload.

5.5: Targets

Local method

route GET profile show => $this->show
method show => view($this->profile)

External class method (static)

route GET api version $major => api::getVersion($major)

What a route may return

The dispatcher inspects the return value for exactly one thing: false means "not my route" and matching continues with the next candidate. Every other return value is discarded.

Lesson. The assumption "a route returns its response body" produces route GET hello => 'Hello': the route matches and serves a 200 with an empty page. A route produces output exclusively through view(), apply(), output(), location() or the %res API.

The false contract is also a tool: a catch-all route GET guide $slug that returns false for unknown slugs lets a literal route in a later file (GET guide index.json) still match the same URL.

5.6: Activating the router

Routes are only matched after:

app::route()

Place this call, for example, in app.phlo (or another central controller) after your app initialization and before a fallback for 404 handling.

5.7: Recommended structure

We use essential cookies to make this site work. With your permission we also use analytics to improve the site.