mirror of
https://github.com/metosin/reitit.git
synced 2026-01-03 15:08:25 +00:00
Updated docs
This commit is contained in:
parent
715968a5d2
commit
39e2e1b11e
6 changed files with 143 additions and 104 deletions
|
|
@ -10,6 +10,9 @@
|
|||
* [Route Conflicts](basics/route_conflicts.md)
|
||||
* [Coercion](coercion/README.md)
|
||||
* [Coercion Explained](coercion/coercion.md)
|
||||
* [Plumatic Schema](coercion/schema_coercion.md)
|
||||
* [Clojure.spec](coercion/clojure_spec_coercion.md)
|
||||
* [Data-specs](coercion/data_spec_coercion.md)
|
||||
* [Advanced](advanced/README.md)
|
||||
* [Configuring Routers](advanced/configuring_routers.md)
|
||||
* [Different Routers](advanced/different_routers.md)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
# Coercion
|
||||
|
||||
* [Coercion Explained](coercion.md)
|
||||
* [Plumatic Schema](schema_coercion.md)
|
||||
* [Clojure.spec](clojure_spec_coercion.md)
|
||||
* [Data-specs](data_spec_coercion.md)
|
||||
|
|
|
|||
50
doc/coercion/clojure_spec_coercion.md
Normal file
50
doc/coercion/clojure_spec_coercion.md
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# Clojure.spec Coercion
|
||||
|
||||
The [clojure.spec](https://clojure.org/guides/spec) library specifies the structure of data, validates or destructures it, and can generate data based on the spec.
|
||||
|
||||
**NOTE**: Currently, `clojure.spec` [doesn't support runtime transformations via conforming](https://dev.clojure.org/jira/browse/CLJ-2116), so one needs to wrap all specs into [Spec Records](https://github.com/metosin/spec-tools/blob/master/README.md#spec-records) to get the coercion working.
|
||||
|
||||
```clj
|
||||
(require '[reitit.coercion.spec])
|
||||
(require '[reitit.coercion :as coercion])
|
||||
(require '[spec-tools.spec :as spec])
|
||||
(require '[clojure.spec.alpha :as s])
|
||||
(require '[reitit.core :as r])
|
||||
|
||||
;; need to wrap the primitives!
|
||||
(s/def ::company spec/string?)
|
||||
(s/def ::user-id spec/int?)
|
||||
(s/def ::path-params (s/keys :req-un [::company ::user-id]))
|
||||
|
||||
(def router
|
||||
(r/router
|
||||
["/:company/users/:user-id" {:name ::user-view
|
||||
:coercion reitit.coercion.spec/coercion
|
||||
:parameters {:path ::path-params}}]
|
||||
{:compile coercion/compile-request-coercers}))
|
||||
|
||||
(defn route-and-coerce! [path]
|
||||
(if-let [match (r/match-by-path router path)]
|
||||
(assoc match :parameters (coercion/coerce! match))))
|
||||
```
|
||||
|
||||
Successful coercion:
|
||||
|
||||
```clj
|
||||
(route-and-coerce! "/metosin/users/123")
|
||||
; #Match{:template "/:company/users/:user-id",
|
||||
; :data {:name :user/user-view,
|
||||
; :coercion #SpecCoercion{...}
|
||||
; :parameters {:path ::path-params}},
|
||||
; :result {:path #object[reitit.coercion$request_coercer$]},
|
||||
; :params {:company "metosin", :user-id "123"},
|
||||
; :parameters {:path {:company "metosin", :user-id 123}}
|
||||
; :path "/metosin/users/123"}
|
||||
```
|
||||
|
||||
Failing coercion:
|
||||
|
||||
```clj
|
||||
(route-and-coerce! "/metosin/users/ikitommi")
|
||||
; => ExceptionInfo Request coercion failed...
|
||||
```
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
# Coercion
|
||||
|
||||
Coercion is a process of transforming parameters from one format into another.
|
||||
|
||||
By default, all wildcard and catch-all parameters are parsed as Strings:
|
||||
|
||||
```clj
|
||||
(require '[reitit.core :as r])
|
||||
|
||||
(def router
|
||||
(r/router
|
||||
["/:company/users/:user-id" ::user-view]))
|
||||
```
|
||||
|
||||
Here's a match:
|
||||
|
||||
```clj
|
||||
(r/match-by-path r "/metosin/users/123")
|
||||
; #Match{:template "/:company/users/:user-id",
|
||||
; :data {:name :user/user-view},
|
||||
; :result nil,
|
||||
; :params {:company "metosin", :user-id "123"},
|
||||
; :path "/metosin/users/123"}
|
||||
```
|
||||
|
||||
To enable parameter coercion, we need to do few things:
|
||||
|
||||
1. Choose a `Coercion` for the routes
|
||||
2. Defined types for the parameters
|
||||
3. Compile coercers for the types
|
||||
4. Apply the coercion
|
||||
|
||||
## Coercion
|
||||
|
||||
`Coercion` is a protocol defining how types can be defined, coerced and inventoried.
|
||||
|
||||
Reitit ships with the following coercion modules:
|
||||
|
||||
* `reitit.coercion.schema/coercion` for [plumatic schema](https://github.com/plumatic/schema).
|
||||
* `reitit.coercion.spec/coercion` for both [clojure.spec](https://clojure.org/about/spec) and [data-specs](https://github.com/metosin/spec-tools#data-specs).
|
||||
|
||||
Coercion can be attached to routes using a `:coercion` key in the route data. There can be multiple `Coercion` implementation into a single router, normal [scoping rules](../basics/route_data.html#nested-route-data) apply here too.
|
||||
|
||||
## Defining types for parameters
|
||||
|
||||
Route parameters can be defined via route data `:parameters`. It can be submaps to define different types of parameters: `:query`, `:body`, `:form`, `:header` and `:path`. Syntax for the actual parameters is defined by the `Coercion` being used.
|
||||
|
||||
#### Schema
|
||||
|
||||
```clj
|
||||
(require '[reitit.coercion.schema])
|
||||
(require '[schema.core :as schema])
|
||||
|
||||
(def router
|
||||
(r/router
|
||||
["/:company/users/:user-id" {:name ::user-view
|
||||
:coercion reitit.coercion.schema/coercion
|
||||
:parameters {:path {:company schema/Str
|
||||
:user-id schema/Int}]))
|
||||
```
|
||||
|
||||
#### Clojure.spec
|
||||
|
||||
Currently, `clojure.spec` [doesn't support runtime transformations via conforming](https://dev.clojure.org/jira/browse/CLJ-2116), so one needs to wrap all specs with `spec-tools.core/spec` to get this working.
|
||||
|
||||
|
||||
```clj
|
||||
(require '[reitit.coercion.spec])
|
||||
(require '[spec-tools.spec :as spec])
|
||||
(require '[clojure.spec :as s])
|
||||
|
||||
(s/def ::company spec/string?
|
||||
(s/def ::user-id spec/int?
|
||||
(s/def ::path-params (s/keys :req-un [::company ::user-id]))
|
||||
|
||||
(def router
|
||||
(r/router
|
||||
["/:company/users/:user-id" {:name ::user-view
|
||||
:coercion reitit.coercion.spec/coercion
|
||||
:parameters {:path ::path-params]))
|
||||
```
|
||||
|
||||
#### Data-specs
|
||||
|
||||
```clj
|
||||
(require '[reitit.coercion.spec])
|
||||
|
||||
(def router
|
||||
(r/router
|
||||
["/:company/users/:user-id" {:name ::user-view
|
||||
:coercion reitit.coercion.spec/coercion
|
||||
:parameters {:path {:company str?
|
||||
:user-id int?}]))
|
||||
```
|
||||
|
||||
So, now we have our
|
||||
|
||||
|
||||
### Thanks to
|
||||
|
||||
Most of the thing are just redefined version of the original implementation. Big thanks to:
|
||||
|
||||
* [compojure-api](https://clojars.org/metosin/compojure-api) for the initial `Coercion` protocol
|
||||
* [ring-swagger](https://github.com/metosin/ring-swagger#more-complete-example) for the syntax for the `:paramters` (and `:responses`).
|
||||
43
doc/coercion/data_spec_coercion.md
Normal file
43
doc/coercion/data_spec_coercion.md
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# Data-spec Coercion
|
||||
|
||||
[Data-specs](https://github.com/metosin/spec-tools#data-specs) is alternative, macro-free syntax to define `clojure.spec`s. As a bonus, supports the [runtime transformations via conforming](https://dev.clojure.org/jira/browse/CLJ-2116) out-of-the-box.
|
||||
|
||||
```clj
|
||||
(require '[reitit.coercion.spec])
|
||||
(require '[reitit.coercion :as coercion])
|
||||
(require '[reitit.core :as r])
|
||||
|
||||
(def router
|
||||
(r/router
|
||||
["/:company/users/:user-id" {:name ::user-view
|
||||
:coercion reitit.coercion.spec/coercion
|
||||
:parameters {:path {:company string?
|
||||
:user-id int?}}}]
|
||||
{:compile coercion/compile-request-coercers}))
|
||||
|
||||
(defn route-and-coerce! [path]
|
||||
(if-let [match (r/match-by-path router path)]
|
||||
(assoc match :parameters (coercion/coerce! match))))
|
||||
```
|
||||
|
||||
Successful coercion:
|
||||
|
||||
```clj
|
||||
(route-and-coerce! "/metosin/users/123")
|
||||
; #Match{:template "/:company/users/:user-id",
|
||||
; :data {:name :user/user-view,
|
||||
; :coercion #SpecCoercion{...}
|
||||
; :parameters {:path {:company string?,
|
||||
; :user-id int?}}},
|
||||
; :result {:path #object[reitit.coercion$request_coercer$]},
|
||||
; :params {:company "metosin", :user-id "123"},
|
||||
; :parameters {:path {:company "metosin", :user-id 123}}
|
||||
; :path "/metosin/users/123"}
|
||||
```
|
||||
|
||||
Failing coercion:
|
||||
|
||||
```clj
|
||||
(route-and-coerce! "/metosin/users/ikitommi")
|
||||
; => ExceptionInfo Request coercion failed...
|
||||
```
|
||||
44
doc/coercion/schema_coercion.md
Normal file
44
doc/coercion/schema_coercion.md
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# Plumatic Schema Coercion
|
||||
|
||||
[Plumatic Schema](https://github.com/plumatic/schema) is a Clojure(Script) library for declarative data description and validation.
|
||||
|
||||
```clj
|
||||
(require '[reitit.coercion.schema])
|
||||
(require '[reitit.coercion :as coercion])
|
||||
(require '[schema.core :as s])
|
||||
(require '[reitit.core :as r])
|
||||
|
||||
(def router
|
||||
(r/router
|
||||
["/:company/users/:user-id" {:name ::user-view
|
||||
:coercion reitit.coercion.schema/coercion
|
||||
:parameters {:path {:company s/Str
|
||||
:user-id s/Int}}}]
|
||||
{:compile coercion/compile-request-coercers}))
|
||||
|
||||
(defn route-and-coerce! [path]
|
||||
(if-let [match (r/match-by-path router path)]
|
||||
(assoc match :parameters (coercion/coerce! match))))
|
||||
```
|
||||
|
||||
Successful coercion:
|
||||
|
||||
```clj
|
||||
(route-and-coerce! "/metosin/users/123")
|
||||
; #Match{:template "/:company/users/:user-id",
|
||||
; :data {:name :user/user-view,
|
||||
; :coercion #SchemaCoercion{...}
|
||||
; :parameters {:path {:company java.lang.String,
|
||||
; :user-id Int}}},
|
||||
; :result {:path #object[reitit.coercion$request_coercer$]},
|
||||
; :params {:company "metosin", :user-id "123"},
|
||||
; :parameters {:path {:company "metosin", :user-id 123}}
|
||||
; :path "/metosin/users/123"}
|
||||
```
|
||||
|
||||
Failing coercion:
|
||||
|
||||
```clj
|
||||
(route-and-coerce! "/metosin/users/ikitommi")
|
||||
; => ExceptionInfo Request coercion failed...
|
||||
```
|
||||
Loading…
Reference in a new issue