# orca.web.router

> A module of morca's API.

The router: a table of routes, each a method, a path pattern, what kind of request it is and the handler that answers it. `orca.web.routes` is the table; `orca.web.server` looks a request up here and wraps the handler in what its kind needs.

A pattern is the path's segments: a literal (`runs`), a parameter
(`{name}`: any segment but an empty one, URL-decoded) or a number
(`{id:int}`). A path matches a route of its length whose literals are its
segments and whose numbers parse. A path that would match but for a number
that isn't one (`/runs/x`, `/runs/1/attempts/x/log`) is answered 404,
"no run x", from the route's `noun`.

A `GET` route answers `HEAD` too. A read (`GET`) that matches nothing is
404, "nothing at <path>"; a `POST` that matches nothing is 405, since only
the actions take one, unless it's an action's but for its number, which
is 404.

## Structs

### `Call`

```mojo
struct Call
```

A request as its handler sees it: where it went, the route's parameters, its form and who sent it.

Implements: `Movable`

Fields:

- `url: String`: The path and its query, as asked.
- `path: String`
- `params: Dict[String, String]`
- `form: String`: A `POST`'s fields, `application/x-www-form-urlencoded` (a JSON body is converted, `orca.web.auth.json_form`).
- `body: String`: The body as it was sent.
- `user: String`: Who's logged in (a session or an API token), or empty (`orca.web.auth.sign_in`).
- `source: String`: How they're logged in: "ui" (a session) or "cli" (an API token).
- `bearer: String`: The API token it was sent with, or empty.
- `session: String`: The session cookie it was sent with, or empty.
- `address: String`: The address it came from (`orca.web.auth.client`).

#### `__init__`

```mojo
def __init__(out self, url: String, path: String)
```

#### `query`

```mojo
def query(self, name: StringSpan) -> String
```

A query parameter's value, decoded, or empty.

#### `field`

```mojo
def field(self, name: StringSpan) -> String
```

A field of the form, decoded, or empty.

#### `param`

```mojo
def param(self, name: String) -> String
```

A `{name}` of the route's pattern, decoded.

#### `int`

```mojo
def int(self, name: String) -> Int
```

A `{name:int}` of the route's pattern.

### `Route`

```mojo
struct Route
```

Implements: `Copyable`, `Movable`

Fields:

- `methods: Int`: `GET`, `POST` or both (`GET | POST`).
- `pattern: StaticString`
- `kind: Int`: `PAGE`, `ACTION` or `AUTH`.
- `handler: def(mut State, Call) raises thin -> Page`
- `noun: StaticString`: What the pattern's number names, for the 404 of one that isn't: "run" answers "no run x".

### `Found`

```mojo
struct Found
```

The route a request matched, with its parameters; or, without one, the 404 of a number that isn't one (`miss`), or nothing.

Implements: `Movable`

Fields:

- `route: Optional[Route]`
- `params: Dict[String, String]`
- `miss: String`

#### `__init__`

```mojo
def __init__(out self)
```

## Functions

### `page`

```mojo
def page(pattern: StringSpan[ImmStaticOrigin], handler: def(mut State, Call) raises thin -> Page, noun: StringSpan[ImmStaticOrigin] = StringSpan("")) -> Route
```

A read at `pattern`.

### `action`

```mojo
def action(pattern: StringSpan[ImmStaticOrigin], handler: def(mut State, Call) raises thin -> Page, noun: StringSpan[ImmStaticOrigin] = StringSpan("")) -> Route
```

A `POST` at `pattern` that changes something.

### `auth`

```mojo
def auth(pattern: StringSpan[ImmStaticOrigin], handler: def(mut State, Call) raises thin -> Page) -> Route
```

Logging in or out at `pattern`, by `GET` or `POST`.

### `find`

```mojo
def find(routes: List[Route], method: String, path: String) -> Found
```

The first route of `routes` for `method` that `path` matches.

### `answer`

```mojo
def answer(routes: List[Route], mut db: State, var call: Call, kind: Int) -> Optional[Page]
```

What the `PAGE` or `ACTION` route `call.path` names answers, for `orca` commands over the database (`orca.web.server.read_page`, `act`): for no such page a 404, and for no such action None.

## Aliases

### `GET`

```mojo
comptime GET = 1
```

`GET`, and `HEAD` with it.

### `POST`

```mojo
comptime POST = 2
```

### `PAGE`

```mojo
comptime PAGE = 0
```

A read: the page, its JSON or a fragment of it. Its header says who's logged in.

### `ACTION`

```mojo
comptime ACTION = 1
```

A `POST` that changes something (`orca.api.actions`): it needs a session once login is on, and is audited as its user's.

### `AUTH`

```mojo
comptime AUTH = 2
```

Logging in and out (`orca.web.auth`), answered as the handler says.

### `Endpoint`

```mojo
comptime Endpoint = def(mut State, Call) raises thin -> Page
```

What answers a route: a page, its JSON and where to go, as `Page`.
