Update README, fix NPE with match-by-name

This commit is contained in:
Tommi Reiman 2017-08-17 08:54:54 +03:00
parent 1bd236f477
commit 038dfd11ae
3 changed files with 26 additions and 22 deletions

View file

@ -1,6 +1,6 @@
# reitit [![Build Status](https://travis-ci.org/metosin/reitit.svg?branch=master)](https://travis-ci.org/metosin/reitit) [![Dependencies Status](https://jarkeeper.com/metosin/reitit/status.svg)](https://jarkeeper.com/metosin/reitit) # reitit [![Build Status](https://travis-ci.org/metosin/reitit.svg?branch=master)](https://travis-ci.org/metosin/reitit) [![Dependencies Status](https://jarkeeper.com/metosin/reitit/status.svg)](https://jarkeeper.com/metosin/reitit)
Snappy data-driven router for Clojure(Script). A friendly data-driven router for Clojure(Script).
* Simple data-driven route syntax * Simple data-driven route syntax
* First-class route meta-data * First-class route meta-data
@ -14,7 +14,7 @@ Snappy data-driven router for Clojure(Script).
## Route Syntax ## Route Syntax
Routes are defined as vectors, which String path as the first element, then optional meta-data (non-vector) and optional child routes. Routes can be wrapped in vectors. Routes are defined as vectors, which String path, optional (non-vector) route argument and optional child routes. Routes can be wrapped in vectors.
Simple route: Simple route:
@ -53,7 +53,7 @@ Nested routes with meta-data:
["/ping" ::ping]] ["/ping" ::ping]]
``` ```
Previous example flattened: Same routes flattened:
```clj ```clj
[["/api/admin/user" {:middleware [::admin], :name ::user} [["/api/admin/user" {:middleware [::admin], :name ::user}
@ -63,9 +63,9 @@ Previous example flattened:
## Routers ## Routers
For actual routing, we need to create a `Router`. Reitit ships with 2 different router implementations: `LinearRouter` and `LookupRouter`, both based on the awesome [Pedestal](https://github.com/pedestal/pedestal/tree/master/route) implementation. For routing, a `Router` is needed. Reitit ships with 2 different router implementations: `LinearRouter` and `LookupRouter`, both based on the awesome [Pedestal](https://github.com/pedestal/pedestal/tree/master/route) implementation.
`Router` is created with `reitit.core/router`, which takes routes and optionally an options map as arguments. The route-tree gets expanded, optionally coerced and compiled to support both fast path- and name-based lookups. `Router` is created with `reitit.core/router`, which takes routes and optional options map as arguments. The route-tree gets expanded, optionally coerced and compiled. `Router` support both fast path- and name-based lookups.
Creating a router: Creating a router:
@ -197,7 +197,7 @@ Simple [Ring](https://github.com/ring-clojure/ring)-based routing app:
["/ping" handler]))) ["/ping" handler])))
``` ```
It's backed by a `LookupRouter` (no wildcards!) Backed by a `LookupRouter` (as no wildcards found):
```clj ```clj
(-> app (ring/get-router) class) (-> app (ring/get-router) class)
@ -237,7 +237,7 @@ Routing based on `:request-method`:
; nil ; nil
``` ```
Define some middleware and a new handler: Some middleware and a new handler:
```clj ```clj
(defn wrap [handler id] (defn wrap [handler id]
@ -283,7 +283,7 @@ Ring-router supports also 3-arity [Async Ring](https://www.booleanknot.com/blog/
### Meta-data based extensions ### Meta-data based extensions
The routing `Match` is injected into a request and can be extracted with `reitit.ring/get-match` helper. It can be used to build dynamic extensions to the system. The routing `Match` is injected into a request and can be extracted with `reitit.ring/get-match`. It can be used to build dynamic extensions to the system.
A middleware to guard routes: A middleware to guard routes:
@ -334,27 +334,25 @@ Authorized access to guarded route:
; {:status 200, :body "ok"} ; {:status 200, :body "ok"}
``` ```
## Validating route-tree
**TODO**
## Merging route-trees ## Merging route-trees
**TODO** *TODO*
## Validating meta-data
*TODO*
## Schema, Spec, Swagger & Openapi ## Schema, Spec, Swagger & Openapi
**TODO** *TODO*
## Interceptors ## Interceptors
**TODO** *TODO*
## Configuring Routers ## Configuring Routers
Routers can be configured via options to do things like custom coercion and compilatin of meta-data. These can be used to do things like [`clojure.spec`](https://clojure.org/about/spec) validation of meta-data and fast, compiled [Ring](https://github.com/ring-clojure/ring/wiki/Concepts) or [Pedestal](http://pedestal.io/) -style handlers. Routers can be configured via options. Options allow things like [`clojure.spec`](https://clojure.org/about/spec) validation for meta-data and fast, compiled handlers. The following options are available for the `reitit.core/router`:
The following options are available for the `Router`:
| key | description | | key | description |
| -----------|-------------| | -----------|-------------|

View file

@ -85,9 +85,11 @@
(reduced (->Match (:path route) (:meta route) path (:handler route) params)))) (reduced (->Match (:path route) (:meta route) path (:handler route) params))))
nil data)) nil data))
(match-by-name [_ name] (match-by-name [_ name]
((lookup name) nil)) (if-let [match (lookup name)]
(match nil)))
(match-by-name [_ name params] (match-by-name [_ name params]
((lookup name) params))) (if-let [match (lookup name)]
(match params))))
(defn linear-router (defn linear-router
"Creates a [[LinearRouter]] from resolved routes and optional "Creates a [[LinearRouter]] from resolved routes and optional
@ -112,9 +114,11 @@
(match-by-path [_ path] (match-by-path [_ path]
(data path)) (data path))
(match-by-name [_ name] (match-by-name [_ name]
((lookup name) nil)) (if-let [match (lookup name)]
(match nil)))
(match-by-name [_ name params] (match-by-name [_ name params]
((lookup name) params))) (if-let [match (lookup name)]
(match params))))
(defn lookup-router (defn lookup-router
"Creates a [[LookupRouter]] from resolved routes and optional "Creates a [[LookupRouter]] from resolved routes and optional

View file

@ -24,6 +24,7 @@
:path "/api/ipa/large" :path "/api/ipa/large"
:params {:size "large"}}) :params {:size "large"}})
(reitit/match-by-name router ::beer {:size "large"}))) (reitit/match-by-name router ::beer {:size "large"})))
(is (= nil (reitit/match-by-name router "ILLEGAL")))
(testing "name-based routing at runtime for missing parameters" (testing "name-based routing at runtime for missing parameters"
(is (thrown-with-msg? (is (thrown-with-msg?
ExceptionInfo ExceptionInfo
@ -47,6 +48,7 @@
:path "/api/ipa/large" :path "/api/ipa/large"
:params {:size "large"}}) :params {:size "large"}})
(reitit/match-by-name router ::beer {:size "large"}))) (reitit/match-by-name router ::beer {:size "large"})))
(is (= nil (reitit/match-by-name router "ILLEGAL")))
(testing "can't be created with wildcard routes" (testing "can't be created with wildcard routes"
(is (thrown-with-msg? (is (thrown-with-msg?
ExceptionInfo ExceptionInfo