mirror of
https://github.com/metosin/reitit.git
synced 2026-02-18 00:35:55 +00:00
Improved frontend docs
This commit is contained in:
parent
78decdb23e
commit
ec1463ed00
3 changed files with 97 additions and 12 deletions
|
|
@ -1,12 +1,31 @@
|
||||||
# Frontend basics
|
# Frontend basics
|
||||||
|
|
||||||
* https://github.com/metosin/reitit/tree/master/examples/frontend
|
Reitit frontend integration is built from multiple layers:
|
||||||
|
|
||||||
|
- Core functions which are enchanted with few browser specific
|
||||||
|
features
|
||||||
|
- [Browser integration](./browser.md) for attaching Reitit to hash-change or HTML5
|
||||||
|
history events
|
||||||
|
- Stateful wrapper for easy use of history integration
|
||||||
|
- Optional [controller extension](./controllers.md)
|
||||||
|
|
||||||
|
## Core functions
|
||||||
|
|
||||||
`reitit.frontend` provides few useful functions wrapping core functions:
|
`reitit.frontend` provides few useful functions wrapping core functions:
|
||||||
|
|
||||||
- `match-by-path` version which parses a URI using JavaScript, including
|
`match-by-path` version which parses a URI using JavaScript, including
|
||||||
query-string, and also coerces the parameters.
|
query-string, and also [coerces the parameters](../coercion/coercion.md).
|
||||||
- `router` which compiles coercers by default
|
Coerced parameters are stored in match `:parameters` property. If coercion
|
||||||
- `match-by-name` and `match-by-name!` with optional `path-paramers` and
|
is not enabled, the original parameters are stored in the same property,
|
||||||
logging errors to `console.warn` instead of throwing errors (to prevent
|
to allow the same code to read parameters regardless if coercion is
|
||||||
React breaking due to errors).
|
enabled.
|
||||||
|
|
||||||
|
`router` which compiles coercers by default.
|
||||||
|
|
||||||
|
`match-by-name` and `match-by-name!` with optional `path-paramers` and
|
||||||
|
logging errors to `console.warn` instead of throwing errors to prevent
|
||||||
|
React breaking due to errors.
|
||||||
|
|
||||||
|
## Next
|
||||||
|
|
||||||
|
[Browser integration](./browser.md)
|
||||||
|
|
|
||||||
|
|
@ -21,5 +21,7 @@ Check examples for simple Ring handler example.
|
||||||
## Easy
|
## Easy
|
||||||
|
|
||||||
Reitit frontend routers require storing the state somewhere and passing it to
|
Reitit frontend routers require storing the state somewhere and passing it to
|
||||||
all the calls. Wrapper (`reitit.frontend.easy`) is provided which manages
|
all the calls. Wrapper `reitit.frontend.easy` is provided which manages
|
||||||
router instance and passes the instance to all calls.
|
a router instance and passes the instance to all calls. This should
|
||||||
|
allow easy use in most applications, as browser anyway can only have single
|
||||||
|
event handler for page change events.
|
||||||
|
|
|
||||||
|
|
@ -7,20 +7,84 @@ Controllers run code when a route is entered and left. This can be useful to:
|
||||||
- Load resources
|
- Load resources
|
||||||
- Update application state
|
- Update application state
|
||||||
|
|
||||||
## Authentication
|
Controller is map of:
|
||||||
|
|
||||||
|
- All properties are optional
|
||||||
|
- `:params` function, `match` -> controller parameters
|
||||||
|
- `:start` & `:stop` functions
|
||||||
|
|
||||||
|
Controllers are defined in [route data](../basics/route_data.md) and
|
||||||
|
as vectors, like:
|
||||||
|
|
||||||
|
```
|
||||||
|
["/items"
|
||||||
|
{:name :items
|
||||||
|
:controllers [{:start start-fn, :stop stop-fn)}]}]
|
||||||
|
```
|
||||||
|
|
||||||
|
To built hierarchies of controllers, nested route data can be used,
|
||||||
|
due to how Reitit merges the route data for nested routes the vectors are
|
||||||
|
concatenated:
|
||||||
|
|
||||||
|
```
|
||||||
|
["/items"
|
||||||
|
{:controllers [{:start start-common-fn}]} ;; A
|
||||||
|
[""
|
||||||
|
{:name :items
|
||||||
|
:controllers [{:start start-items-fn}]}] ;; B
|
||||||
|
["/:id"
|
||||||
|
{:name :item
|
||||||
|
;; C
|
||||||
|
:controllers [{:params item-param-fn :start start-item-fn}]}]]
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example both `:items` and `:item` routes inherit `:controllers` from
|
||||||
|
their parent route. Lets call these controllers A, B and C. `:items` route
|
||||||
|
has controllers A and B and `:item` A and C.
|
||||||
|
|
||||||
|
Controller `:start` is called when new matches controllers list contains a
|
||||||
|
controller that is not yet initialized. If either of routes is entered
|
||||||
|
from some other route, `:start` is called for both of routes controllers.
|
||||||
|
If `:item` is entered from `:items` only C `:start` is called, because
|
||||||
|
A controller is identical for both routes. And transition from `:item`
|
||||||
|
back to `:items` would only call B `:start`.
|
||||||
|
|
||||||
|
Controller `:stop` function is called for controllers that were
|
||||||
|
initialized but aren't included in the new match.
|
||||||
|
|
||||||
|
To reinitialize a controller when route itself doesn't change,
|
||||||
|
controllers can provide `:params` function to control their
|
||||||
|
identity based on which parameters they are interested in.
|
||||||
|
|
||||||
|
To make C controller depend on routes `id` path parameter, it should
|
||||||
|
provide following function:
|
||||||
|
|
||||||
|
```clj
|
||||||
|
(defn item-param-fn [match]
|
||||||
|
(select-keys (:path (:parameters match)) [:id]))
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, whenever the result value of this function changes, the identity
|
||||||
|
of controller changes and controller is stopped and started.
|
||||||
|
|
||||||
|
TODO: Provide way to declare params as data.
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
|
||||||
Controllers can be used to load resources from a server. If and when your
|
Controllers can be used to load resources from a server. If and when your
|
||||||
API requires authentication you will need to implement logic to prevent controllers
|
API requires authentication you will need to implement logic to prevent controllers
|
||||||
trying to do requests if user isn't authenticated yet.
|
trying to do requests if user isn't authenticated yet.
|
||||||
|
|
||||||
### Run controllers and check authentication
|
#### Run controllers and check authentication
|
||||||
|
|
||||||
If you have both unauthenticated and authenticated resources, you can
|
If you have both unauthenticated and authenticated resources, you can
|
||||||
run the controllers always and then check the authentication status
|
run the controllers always and then check the authentication status
|
||||||
on controller code, or on the code called from controllers (e.g. re-frame event
|
on controller code, or on the code called from controllers (e.g. re-frame event
|
||||||
handler).
|
handler).
|
||||||
|
|
||||||
### Disable controllers until user is authenticated
|
#### Disable controllers until user is authenticated
|
||||||
|
|
||||||
If all your resources require authentication an easy way to prevent bad
|
If all your resources require authentication an easy way to prevent bad
|
||||||
requests is to enable controllers only after authentication is done.
|
requests is to enable controllers only after authentication is done.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue