Merge remote-tracking branch 'upstream/master' into feature/swagger-ui-v3

This commit is contained in:
heyarne 2020-02-10 15:23:42 +01:00
commit 4c03cd0bf7
51 changed files with 366 additions and 191 deletions

View file

@ -12,7 +12,29 @@ We use [Break Versioning][breakver]. The version numbers follow a `<major>.<mino
[breakver]: https://github.com/ptaoussanis/encore/blob/master/BREAK-VERSIONING.md
## 0.4.0-SNAPSHOT
## 0.4.2 (2020-01-17)
### `reitit`
* Updated deps:
```
[com.fasterxml.jackson.core/jackson-core "2.10.0"]
```
* See https://clojureverse.org/t/depending-on-the-right-versions-of-jackson-libraries/5111
## 0.4.1 (2020-01-14)
### `reitit`
* Updated deps:
```
[metosin/reitit-malli "0.4.1"]
```
## 0.4.0 (2020-01-14)
* Updated deps:

View file

@ -50,7 +50,7 @@ There is [#reitit](https://clojurians.slack.com/messages/reitit/) in [Clojurians
All main modules bundled:
```clj
[metosin/reitit "0.3.10"]
[metosin/reitit "0.4.2"]
```
Optionally, the parts can be required separately.

View file

@ -40,7 +40,7 @@ There is [#reitit](https://clojurians.slack.com/messages/reitit/) in [Clojurians
All bundled:
```clj
[metosin/reitit "0.3.10"]
[metosin/reitit "0.4.2"]
```
Optionally, the parts can be required separately.

View file

@ -34,6 +34,7 @@
* [Transforming Middleware Chain](ring/transforming_middleware_chain.md)
* [Middleware Registry](ring/middleware_registry.md)
* [Default Middleware](ring/default_middleware.md)
* [Content Negotiation](ring/content_negotiation.md)
* [Ring Coercion](ring/coercion.md)
* [Route Data Validation](ring/route_data_validation.md)
* [Compiling Middleware](ring/compiling_middleware.md)

View file

@ -22,7 +22,7 @@ The default exception formatting uses `reitit.exception/exception`. It produces
## Pretty Errors
```clj
[metosin/reitit-dev "0.3.10"]
[metosin/reitit-dev "0.4.2"]
```
For human-readable and developer-friendly exception messages, there is `reitit.dev.pretty/exception` (in the `reitit-dev` module). It is inspired by the lovely errors messages of [ELM](https://elm-lang.org/blog/compiler-errors-for-humans) and [ETA](https://twitter.com/jyothsnasrin/status/1037703436043603968) and uses [fipp](https://github.com/brandonbloom/fipp), [expound](https://github.com/bhb/expound) and [spell-spec](https://github.com/bhauman/spell-spec) for most of heavy lifting.
@ -51,4 +51,4 @@ See the [validating route data](route_data_validation.md) page.
## Runtime Exception
See [Exception Handling with Ring](../ring/exceptions.md).
See [Exception Handling with Ring](exceptions.md).

View file

@ -1,7 +1,7 @@
# Default Interceptors
```clj
[metosin/reitit-interceptors "0.3.10"]
[metosin/reitit-interceptors "0.4.2"]
```
Just like the [ring default middleware](../ring/default_middleware.md), but for interceptors.

View file

@ -5,7 +5,7 @@ Reitit also support for [interceptors](http://pedestal.io/reference/interceptors
## Reitit-http
```clj
[metosin/reitit-http "0.3.10"]
[metosin/reitit-http "0.4.2"]
```
An module for http-routing using interceptors instead of middleware. Builds on top of the [`reitit-ring`](../ring/ring.md) module having all the same features.

View file

@ -3,7 +3,7 @@
[Pedestal](http://pedestal.io/) is a backend web framework for Clojure. `reitit-pedestal` provides an alternative routing engine for Pedestal.
```clj
[metosin/reitit-pedestal "0.3.10"]
[metosin/reitit-pedestal "0.4.2"]
```
Why should one use reitit instead of the Pedestal [default routing](http://pedestal.io/reference/routing-quick-reference)?
@ -26,8 +26,8 @@ A minimalistic example on how to to swap the default-router with a reitit router
```clj
; [io.pedestal/pedestal.service "0.5.5"]
; [io.pedestal/pedestal.jetty "0.5.5"]
; [metosin/reitit-pedestal "0.3.10"]
; [metosin/reitit "0.3.10"]
; [metosin/reitit-pedestal "0.4.2"]
; [metosin/reitit "0.4.2"]
(require '[io.pedestal.http :as server])
(require '[reitit.pedestal :as pedestal])

View file

@ -1,7 +1,7 @@
# Sieppari
```clj
[metosin/reitit-sieppari "0.3.10"]
[metosin/reitit-sieppari "0.4.2"]
```
[Sieppari](https://github.com/metosin/sieppari) is a new and fast interceptor implementation for Clojure, with pluggable async supporting [core.async](https://github.com/clojure/core.async), [Manifold](https://github.com/ztellman/manifold) and [Promesa](http://funcool.github.io/promesa/latest).

View file

@ -65,7 +65,7 @@ There is an extra option in http-router (actually, in the underlying interceptor
### Printing Context Diffs
```clj
[metosin/reitit-interceptors "0.3.10"]
[metosin/reitit-interceptors "0.4.2"]
```
Using `reitit.http.interceptors.dev/print-context-diffs` transformation, the context diffs between each interceptor are printed out to the console. To use it, add the following router option:

View file

@ -0,0 +1,138 @@
# Content Negotiation
Wrapper for [Muuntaja](https://github.com/metosin/muuntaja) middleware for content-negotiation, request decoding and response encoding. Takes explicit configuration via `:muuntaja` key in route data. Emit's [swagger](swagger.md) `:produces` and `:consumes` definitions automatically based on the Muuntaja configuration.
Negotiates a request body based on `Content-Type` header and response body based on `Accept`, `Accept-Charset` headers. Publishes the negotiation results as `:muuntaja/request` and `:muuntaja/response` keys into the request.
Decodes the request body into `:body-params` using the `:muuntaja/request` key in request if the `:body-params` doesn't already exist.
Encodes the response body using the `:muuntaja/response` key in request if the response doesn't have `Content-Type` header already set.
Expected route data:
| key | description |
| -------------|-------------|
| `:muuntaja` | `muuntaja.core/Muuntaja` instance, does not mount if not set.
```clj
(require '[reitit.ring.middleware.muuntaja :as muuntaja])
```
* `muuntaja/format-middleware` - Negotiation, request decoding and response encoding in a single Middleware
* `muuntaja/format-negotiate-middleware` - Negotiation
* `muuntaja/format-request-middleware` - Request decoding
* `muuntaja/format-response-middleware` - Response encoding
```clj
(require '[reitit.ring :as ring])
(require '[reitit.ring.coercion :as rrc])
(require '[reitit.coercion.spec :as rcs])
(require '[ring.adapter.jetty :as jetty])
(require '[muuntaja.core :as m])
(def app
(ring/ring-handler
(ring/router
[["/math"
{:post {:summary "negotiated request & response (json, edn, transit)"
:parameters {:body {:x int?, :y int?}}
:responses {200 {:body {:total int?}}}
:handler (fn [{{{:keys [x y]} :body} :parameters}]
{:status 200
:body {:total (+ x y)}})}}]
["/xml"
{:get {:summary "forced xml response"
:handler (fn [_]
{:status 200
:headers {"Content-Type" "text/xml"}
:body "<kikka>kukka</kikka>"})}}]]
{:data {:muuntaja m/instance
:coercion rcs/coercion
:middleware [muuntaja/format-middleware
rrc/coerce-exceptions-middleware
rrc/coerce-request-middleware
rrc/coerce-response-middleware]}})))
(jetty/run-jetty #'app {:port 3000, :join? false})
```
Testing with [httpie](https://httpie.org/):
```bash
> http POST :3000/math x:=1 y:=2
HTTP/1.1 200 OK
Content-Length: 11
Content-Type: application/json; charset=utf-8
Date: Wed, 22 Aug 2018 16:59:54 GMT
Server: Jetty(9.2.21.v20170120)
{
"total": 3
}
```
```bash
> http :3000/xml
HTTP/1.1 200 OK
Content-Length: 20
Content-Type: text/xml
Date: Wed, 22 Aug 2018 16:59:58 GMT
Server: Jetty(9.2.21.v20170120)
<kikka>kukka</kikka>
```
## Changing default parameters
The current JSON formatter used by `reitit` already have the option to parse keys as `keyword` which is a sane default in Clojure. However, if you would like to parse all the `double` as `bigdecimal` you'd need to change an option of the [JSON formatter](https://github.com/metosin/jsonista)
```clj
(def new-muuntaja-instance
(m/create
(assoc-in
m/default-options
[:formats "application/json" :decoder-opts :bigdecimals]
true)))
```
Now you should change the `m/instance` installed in the router with the `new-muuntaja-instance`.
You can find more options for [JSON](https://cljdoc.org/d/metosin/jsonista/0.2.5/api/jsonista.core#object-mapper) and [EDN].
## Adding custom encoder
The example below is from `muuntaja` explaining how to add a custom encoder to parse a `java.util.Date` instance.
```clj
(def muuntaja-instance
(m/create
(assoc-in
m/default-options
[:formats "application/json" :encoder-opts]
{:date-format "yyyy-MM-dd"})))
(->> {:value (java.util.Date.)}
(m/encode m "application/json")
slurp)
; => "{\"value\":\"2019-10-15\"}"
```
## Adding all together
If you inspect `m/default-options` it's only a map, therefore you can compose your new muuntaja instance with as many options as you need it.
```clj
(def new-muuntaja
(m/create
(-> m/default-options
(assoc-in [:formats "application/json" :decoder-opts :bigdecimals] true)
(assoc-in [:formats "application/json" :encoder-opts :data-format] "yyyy-MM-dd"))))
```

View file

@ -1,7 +1,7 @@
# Default Middleware
```clj
[metosin/reitit-middleware "0.3.10"]
[metosin/reitit-middleware "0.4.2"]
```
Any Ring middleware can be used with `reitit-ring`, but using data-driven middleware is preferred as they are easier to manage and in many cases, yield better performance. `reitit-middleware` contains a set of common ring middleware, lifted into data-driven middleware.
@ -23,91 +23,6 @@ Any Ring middleware can be used with `reitit-ring`, but using data-driven middle
See [Exception Handling with Ring](exceptions.md).
## Content Negotiation
Wrapper for [Muuntaja](https://github.com/metosin/muuntaja) middleware for content-negotiation, request decoding and response encoding. Takes explicit configuration via `:muuntaja` key in route data. Emit's [swagger](swagger.md) `:produces` and `:consumes` definitions automatically based on the Muuntaja configuration.
Negotiates a request body based on `Content-Type` header and response body based on `Accept`, `Accept-Charset` headers. Publishes the negotiation results as `:muuntaja/request` and `:muuntaja/response` keys into the request.
Decodes the request body into `:body-params` using the `:muuntaja/request` key in request if the `:body-params` doesn't already exist.
Encodes the response body using the `:muuntaja/response` key in request if the response doesn't have `Content-Type` header already set.
Expected route data:
| key | description |
| -------------|-------------|
| `:muuntaja` | `muuntaja.core/Muuntaja` instance, does not mount if not set.
```clj
(require '[reitit.ring.middleware.muuntaja :as muuntaja])
```
* `muuntaja/format-middleware` - Negotiation, request decoding and response encoding in a single Middleware
* `muuntaja/format-negotiate-middleware` - Negotiation
* `muuntaja/format-request-middleware` - Request decoding
* `muuntaja/format-response-middleware` - Response encoding
```clj
(require '[reitit.ring :as ring])
(require '[reitit.ring.coercion :as rrc])
(require '[reitit.coercion.spec :as rcs])
(require '[ring.adapter.jetty :as jetty])
(def app
(ring/ring-handler
(ring/router
[["/math"
{:post {:summary "negotiated request & response (json, edn, transit)"
:parameters {:body {:x int?, :y int?}}
:responses {200 {:body {:total int?}}}
:handler (fn [{{{:keys [x y]} :body} :parameters}]
{:status 200
:body {:total (+ x y)}})}}]
["/xml"
{:get {:summary "forced xml response"
:handler (fn [_]
{:status 200
:headers {"Content-Type" "text/xml"}
:body "<kikka>kukka</kikka>"})}}]]
{:data {:muuntaja m/instance
:coercion rcs/coercion
:middleware [muuntaja/format-middleware
rrc/coerce-exceptions-middleware
rrc/coerce-request-middleware
rrc/coerce-response-middleware]}})))
(jetty/run-jetty #'app {:port 3000, :join? false})
```
Testing with [httpie](https://httpie.org/):
```bash
> http POST :3000/math x:=1 y:=2
HTTP/1.1 200 OK
Content-Length: 11
Content-Type: application/json; charset=utf-8
Date: Wed, 22 Aug 2018 16:59:54 GMT
Server: Jetty(9.2.21.v20170120)
{
"total": 3
}
```
```bash
> http :3000/xml
HTTP/1.1 200 OK
Content-Length: 20
Content-Type: text/xml
Date: Wed, 22 Aug 2018 16:59:58 GMT
Server: Jetty(9.2.21.v20170120)
<kikka>kukka</kikka>
```
## Multipart Request Handling
Wrapper for [Ring Multipart Middleware](https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/middleware/multipart_params.clj). Emits swagger `:consumes` definitions automatically.

View file

@ -1,7 +1,7 @@
# Exception Handling with Ring
```clj
[metosin/reitit-middleware "0.3.10"]
[metosin/reitit-middleware "0.4.2"]
```
Exceptions thrown in router creation can be [handled with custom exception handler](../basics/error_messages.md). By default, exceptions thrown at runtime from a handler or a middleware are not caught by the `reitit.ring/ring-handler`. A good practise is a have an top-level exception handler to log and format the errors for clients.

View file

@ -5,7 +5,7 @@
Read more about the [Ring Concepts](https://github.com/ring-clojure/ring/wiki/Concepts).
```clj
[metosin/reitit-ring "0.3.10"]
[metosin/reitit-ring "0.4.2"]
```
## `reitit.ring/ring-router`

View file

@ -1,7 +1,7 @@
# Swagger Support
```
[metosin/reitit-swagger "0.3.10"]
[metosin/reitit-swagger "0.4.2"]
```
Reitit supports [Swagger2](https://swagger.io/) documentation, thanks to [schema-tools](https://github.com/metosin/schema-tools) and [spec-tools](https://github.com/metosin/spec-tools). Documentation is extracted from route definitions, coercion `:parameters` and `:responses` and from a set of new documentation keys.
@ -44,7 +44,7 @@ If you need to post-process the generated spec, just wrap the handler with a cus
[Swagger-ui](https://github.com/swagger-api/swagger-ui) is a user interface to visualize and interact with the Swagger specification. To make things easy, there is a pre-integrated version of the swagger-ui as a separate module.
```
[metosin/reitit-swagger-ui "0.3.10"]
[metosin/reitit-swagger-ui "0.4.2"]
```
`reitit.swagger-ui/create-swagger-ui-hander` can be used to create a ring-handler to serve the swagger-ui. It accepts the following options:

View file

@ -59,7 +59,7 @@ There is an extra option in ring-router (actually, in the underlying middleware-
### Printing Request Diffs
```clj
[metosin/reitit-middleware "0.3.10"]
[metosin/reitit-middleware "0.4.2"]
```
Using `reitit.ring.middleware.dev/print-request-diffs` transformation, the request diffs between each middleware are printed out to the console. To use it, add the following router option:

View file

@ -10,9 +10,9 @@
[ring "1.7.1"]
[hiccup "1.0.5"]
[org.clojure/clojurescript "1.10.439"]
[metosin/reitit "0.3.10"]
[metosin/reitit-schema "0.3.10"]
[metosin/reitit-frontend "0.3.10"]
[metosin/reitit "0.4.2"]
[metosin/reitit-schema "0.4.2"]
[metosin/reitit-frontend "0.4.2"]
;; Just for pretty printting the match
[fipp "0.6.14"]]

View file

@ -10,9 +10,9 @@
[ring "1.7.1"]
[hiccup "1.0.5"]
[org.clojure/clojurescript "1.10.439"]
[metosin/reitit "0.3.10"]
[metosin/reitit-schema "0.3.10"]
[metosin/reitit-frontend "0.3.10"]
[metosin/reitit "0.4.2"]
[metosin/reitit-schema "0.4.2"]
[metosin/reitit-frontend "0.4.2"]
;; Just for pretty printting the match
[fipp "0.6.14"]]

View file

@ -10,9 +10,9 @@
[ring "1.7.1"]
[hiccup "1.0.5"]
[org.clojure/clojurescript "1.10.520"]
[metosin/reitit "0.3.10"]
[metosin/reitit-spec "0.3.10"]
[metosin/reitit-frontend "0.3.10"]
[metosin/reitit "0.4.2"]
[metosin/reitit-spec "0.4.2"]
[metosin/reitit-frontend "0.4.2"]
;; Just for pretty printting the match
[fipp "0.6.14"]]

View file

@ -10,9 +10,9 @@
[ring "1.7.1"]
[hiccup "1.0.5"]
[org.clojure/clojurescript "1.10.520"]
[metosin/reitit "0.3.10"]
[metosin/reitit-spec "0.3.10"]
[metosin/reitit-frontend "0.3.10"]
[metosin/reitit "0.4.2"]
[metosin/reitit-spec "0.4.2"]
[metosin/reitit-frontend "0.4.2"]
;; Just for pretty printting the match
[fipp "0.6.14"]]

View file

@ -1,7 +1,7 @@
(defproject frontend-re-frame "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.10.0"]
[org.clojure/clojurescript "1.10.520"]
[metosin/reitit "0.3.10"]
[metosin/reitit "0.4.2"]
[reagent "0.8.1"]
[re-frame "0.10.6"]]

View file

@ -10,9 +10,9 @@
[ring "1.7.1"]
[hiccup "1.0.5"]
[org.clojure/clojurescript "1.10.439"]
[metosin/reitit "0.3.10"]
[metosin/reitit-spec "0.3.10"]
[metosin/reitit-frontend "0.3.10"]
[metosin/reitit "0.4.2"]
[metosin/reitit-spec "0.4.2"]
[metosin/reitit-frontend "0.4.2"]
;; Just for pretty printting the match
[fipp "0.6.14"]]

View file

@ -3,5 +3,5 @@
:dependencies [[org.clojure/clojure "1.10.0"]
[ring/ring-jetty-adapter "1.7.1"]
[aleph "0.4.7-alpha5"]
[metosin/reitit "0.3.10"]]
[metosin/reitit "0.4.2"]]
:repl-options {:init-ns example.server})

View file

@ -5,5 +5,5 @@
[funcool/promesa "1.9.0"]
[manifold "0.1.8"]
[ring/ring-jetty-adapter "1.7.1"]
[metosin/reitit "0.3.10"]]
[metosin/reitit "0.4.2"]]
:repl-options {:init-ns example.server})

View file

@ -2,4 +2,4 @@
:description "Reitit coercion with vanilla ring"
:dependencies [[org.clojure/clojure "1.10.0"]
[ring/ring-jetty-adapter "1.7.1"]
[metosin/reitit "0.3.10"]])
[metosin/reitit "0.4.2"]])

View file

@ -3,6 +3,6 @@
:dependencies [[org.clojure/clojure "1.10.0"]
[io.pedestal/pedestal.service "0.5.5"]
[io.pedestal/pedestal.jetty "0.5.5"]
[metosin/reitit-pedestal "0.3.10"]
[metosin/reitit "0.3.10"]]
[metosin/reitit-pedestal "0.4.2"]
[metosin/reitit "0.4.2"]]
:repl-options {:init-ns example.server})

View file

@ -3,6 +3,6 @@
:dependencies [[org.clojure/clojure "1.10.0"]
[io.pedestal/pedestal.service "0.5.5"]
[io.pedestal/pedestal.jetty "0.5.5"]
[metosin/reitit-pedestal "0.3.10"]
[metosin/reitit "0.3.10"]]
[metosin/reitit-pedestal "0.4.2"]
[metosin/reitit "0.4.2"]]
:repl-options {:init-ns example.server})

View file

@ -2,5 +2,5 @@
:description "Reitit Ring App"
:dependencies [[org.clojure/clojure "1.10.0"]
[ring/ring-jetty-adapter "1.7.1"]
[metosin/reitit "0.3.10"]]
[metosin/reitit "0.4.2"]]
:repl-options {:init-ns example.server})

View file

@ -2,7 +2,7 @@
:description "Reitit Ring App with Integrant"
:dependencies [[org.clojure/clojure "1.10.1"]
[ring/ring-jetty-adapter "1.7.1"]
[metosin/reitit "0.3.10"]
[metosin/reitit "0.4.2"]
[integrant "0.7.0"]]
:main example.server
:repl-options {:init-ns user}

View file

@ -2,6 +2,6 @@
:description "Reitit Ring App with Swagger"
:dependencies [[org.clojure/clojure "1.10.0"]
[ring/ring-jetty-adapter "1.7.1"]
[metosin/reitit "0.3.10"]]
[metosin/reitit "0.4.2"]]
:repl-options {:init-ns example.server}
:profiles {:dev {:dependencies [[ring/ring-mock "0.3.2"]]}})

View file

@ -2,6 +2,6 @@
:description "Reitit Ring App with Swagger"
:dependencies [[org.clojure/clojure "1.10.0"]
[ring/ring-jetty-adapter "1.7.1"]
[metosin/reitit "0.3.10"]]
[metosin/reitit "0.4.2"]]
:repl-options {:init-ns example.server}
:profiles {:dev {:dependencies [[ring/ring-mock "0.3.2"]]}})

View file

@ -2,5 +2,5 @@
:description "Reitit Ring App with Swagger"
:dependencies [[org.clojure/clojure "1.10.0"]
[ring/ring-jetty-adapter "1.7.1"]
[metosin/reitit "0.3.10"]]
[metosin/reitit "0.4.2"]]
:repl-options {:init-ns example.server})

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit-core "0.3.10"
(defproject metosin/reitit-core "0.4.2"
:description "Snappy data-driven router for Clojure(Script)"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"

View file

@ -22,7 +22,7 @@
(defprotocol Matcher
(match [this i max path])
(view [this])
(depth [this])
(depth ^long [this])
(length [this]))
(defprotocol TrieCompiler
@ -53,7 +53,7 @@
:else (recur (inc i))))))
(defn- -keyword [s]
(if-let [i (str/index-of s "/")]
(if-let [^long i (str/index-of s "/")]
(keyword (subs s 0 i) (subs s (inc i)))
(keyword s)))
@ -61,8 +61,8 @@
(let [bracket? (-> syntax (into-set) :bracket)
colon? (-> syntax (into-set) :colon)
-static (fn [from to] (if-not (= from to) [(subs s from to)]))
-wild (fn [from to] [(->Wild (-keyword (subs s (inc from) to)))])
-catch-all (fn [from to] [(->CatchAll (keyword (subs s (inc from) to)))])]
-wild (fn [^long from to] [(->Wild (-keyword (subs s (inc from) to)))])
-catch-all (fn [^long from to] [(->CatchAll (keyword (subs s (inc from) to)))])]
(loop [ss nil, from 0, to 0]
(if (= to (count s))
(concat ss (-static from to))
@ -70,13 +70,13 @@
(cond
(and bracket? (= \{ c))
(let [to' (or (str/index-of s "}" to) (ex/fail! ::unclosed-brackets {:path s}))]
(let [^long to' (or (str/index-of s "}" to) (ex/fail! ::unclosed-brackets {:path s}))]
(if (= \* (get s (inc to)))
(recur (concat ss (-static from to) (-catch-all (inc to) to')) (long (inc to')) (long (inc to')))
(recur (concat ss (-static from to) (-wild to to')) (long (inc to')) (long (inc to')))))
(and colon? (= \: c))
(let [to' (or (str/index-of s "/" to) (count s))]
(let [^long to' (or (str/index-of s "/" to) (count s))]
(if (= 1 (- to' to))
(recur ss from (inc to))
(recur (concat ss (-static from to) (-wild to to')) (long to') (long to'))))
@ -115,7 +115,7 @@
(and (string? cp) (not= (count cp) (count p))) [(subs p (count cp))]
(and (string? p) (not cp)) (-split p)))
-postcut (fn [[p :as pps]]
(let [i (and p (str/index-of p "/"))]
(let [^long i (and p (str/index-of p "/"))]
(if (and i (pos? i))
(concat [(subs p 0 i) (subs p i)] (rest pps))
pps)))
@ -128,7 +128,7 @@
(defn- -slice-end [x xs]
(let [i (if (string? x) (str/index-of x "/"))]
(if (and (number? i) (pos? i))
(if (and (number? i) (pos? ^long i))
(concat [(subs x i)] xs)
xs)))
@ -227,11 +227,11 @@
(let [size (count path)]
(reify Matcher
(match [_ i max p]
(if-not (< max (+ i size))
(if-not (< ^long max (+ ^long i size))
(loop [j 0]
(if (= j size)
(match matcher (+ i size) max p)
(if (= (get p (+ i j)) (get path j))
(match matcher (+ ^long i size) max p)
(if (= (get p (+ ^long i j)) (get path j))
(recur (inc j)))))))
(view [_] [path (view matcher)])
(depth [_] (inc (depth matcher)))
@ -239,8 +239,8 @@
(wild-matcher [_ key end matcher]
(reify Matcher
(match [_ i max path]
(if (and (< i max) (not= (get path i) end))
(loop [percent? false, j i]
(if (and (< ^long i ^long max) (not= (get path i) end))
(loop [percent? false, j ^long i]
(if (= max j)
(if-let [match (match matcher max max path)]
(assoc-param match key (decode path i max percent?)))
@ -257,7 +257,7 @@
(let [match (->Match params data)]
(reify Matcher
(match [_ i max path]
(if (<= i max) (assoc-param match key (decode path i max true))))
(if (<= ^long i ^long max) (assoc-param match key (decode path i max true))))
(view [_] [key [data]])
(depth [_] 1)
(length [_]))))
@ -271,7 +271,7 @@
(or (match (get matchers j) i max path)
(recur (inc j))))))
(view [_] (mapv view matchers))
(depth [_] (inc (apply max 0 (map depth matchers))))
(depth [_] (inc ^long (apply max 0 (map depth matchers))))
(length [_]))))
(-pretty [_ matcher]
(view matcher))

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit-dev "0.3.10"
(defproject metosin/reitit-dev "0.4.2"
:description "Snappy data-driven router for Clojure(Script)"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit-frontend "0.3.10"
(defproject metosin/reitit-frontend "0.4.2"
:description "Reitit: Clojurescript frontend routing core"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit-http "0.3.10"
(defproject metosin/reitit-http "0.4.2"
:description "Reitit: HTTP routing with interceptors"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit-interceptors "0.3.10"
(defproject metosin/reitit-interceptors "0.4.2"
:description "Reitit, common interceptors bundled"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit-malli "0.3.10"
(defproject metosin/reitit-malli "0.4.2"
:description "Reitit: Malli coercion"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"

View file

@ -75,18 +75,18 @@
;; swagger
;;
(defmulti extract-parameter (fn [in _] in))
(defmulti extract-parameter (fn [in _ _] in))
(defmethod extract-parameter :body [_ schema]
(let [swagger-schema (swagger/transform schema {:in :body, :type :parameter})]
(defmethod extract-parameter :body [_ schema options]
(let [swagger-schema (swagger/transform schema (merge options {:in :body, :type :parameter}))]
[{:in "body"
:name (:title swagger-schema "")
:description (:description swagger-schema "")
:required (not= :maybe (m/name schema))
:schema swagger-schema}]))
(defmethod extract-parameter :default [in schema]
(let [{:keys [properties required]} (swagger/transform schema {:in in, :type :parameter})]
(defmethod extract-parameter :default [in schema options]
(let [{:keys [properties required]} (swagger/transform schema (merge options {:in in, :type :parameter}))]
(mapv
(fn [[k {:keys [type] :as schema}]]
(merge
@ -135,7 +135,7 @@
(if parameters
{:parameters
(->> (for [[in schema] parameters
parameter (extract-parameter in (compile schema))]
parameter (extract-parameter in (compile schema options) options)]
parameter)
(into []))})
(if responses
@ -148,14 +148,14 @@
(update $ :description (fnil identity ""))
(if (:schema $)
(-> $
(update :schema compile)
(update :schema compile options)
(update :schema swagger/transform {:type :schema}))
$))]))}))
(throw
(ex-info
(str "Can't produce Schema apidocs for " specification)
{:type specification, :coercion :schema}))))
(-compile-model [_ model _] (compile model))
(-compile-model [_ model _] (compile model options))
(-open-model [_ schema] schema)
(-encode-error [_ error]
(cond-> error
@ -165,9 +165,9 @@
(update :errors (partial map #(update % :schema edn/write-string opts))))
(seq error-keys) (select-keys error-keys)))
(-request-coercer [_ type schema]
(-coercer (compile schema) type transformers :decode nil options))
(-coercer (compile schema options) type transformers :decode nil options))
(-response-coercer [_ schema]
(let [schema (compile schema)
(let [schema (compile schema options)
encoder (-coercer schema :body transformers :encode nil options)]
(-coercer schema :response transformers :encode encoder options)))))))

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit-middleware "0.3.10"
(defproject metosin/reitit-middleware "0.4.2"
:description "Reitit, common middleware bundled"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit-pedestal "0.3.10"
(defproject metosin/reitit-pedestal "0.4.2"
:description "Reitit + Pedestal Integration"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit-ring "0.3.10"
(defproject metosin/reitit-ring "0.4.2"
:description "Reitit: Ring routing"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit-schema "0.3.10"
(defproject metosin/reitit-schema "0.4.2"
:description "Reitit: Plumatic Schema coercion"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit-sieppari "0.3.10"
(defproject metosin/reitit-sieppari "0.4.2"
:description "Reitit: Sieppari Interceptors"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit-spec "0.3.10"
(defproject metosin/reitit-spec "0.4.2"
:description "Reitit: clojure.spec coercion"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit-swagger-ui "0.3.10"
(defproject metosin/reitit-swagger-ui "0.4.2"
:description "Reitit: Swagger-ui support"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit-swagger "0.3.10"
(defproject metosin/reitit-swagger "0.4.2"
:description "Reitit: Swagger-support"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit "0.3.10"
(defproject metosin/reitit "0.4.2"
:description "Snappy data-driven router for Clojure(Script)"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"
@ -12,6 +12,7 @@
:dependencies [[metosin/reitit-core]
[metosin/reitit-dev]
[metosin/reitit-spec]
[metosin/reitit-malli]
[metosin/reitit-schema]
[metosin/reitit-ring]
[metosin/reitit-middleware]
@ -20,4 +21,7 @@
[metosin/reitit-swagger]
[metosin/reitit-swagger-ui]
[metosin/reitit-frontend]
[metosin/reitit-sieppari]])
[metosin/reitit-sieppari]
;; https://clojureverse.org/t/depending-on-the-right-versions-of-jackson-libraries/5111
[com.fasterxml.jackson.core/jackson-core]])

View file

@ -10,6 +10,8 @@
[compojure.core :refer [routes context ANY]]
[calfpath.core :as cp]
[calfpath.route :as cr]
[janus.route :as janus]
[janus.ring :as janus.ring]
[io.pedestal.http.route.definition.table :as table]
[io.pedestal.http.route.map-tree :as map-tree]
@ -309,6 +311,91 @@
(ANY "/topics/:topic" [] {:name :test/route47} handler)
(ANY "/topics" [] {:name :test/route50} handler))))
(def opensensors-janus-routes
(janus/router
['root
{:v1 ["v1" handler
[[:public ["public" handler
[[:topics ["topics" handler {:test/route4 [true handler]}]]
[:users ["users" handler {:test/route16 [true handler]}]]
[:orgs ["orgs" handler {:test/route18 [true handler]}]]]]]
[:users ["users" handler
{:test/route36 [true handler
[[:orgs ["orgs" handler {:test/route5 [true handler]}]]
[:test/route7 ["invitations" handler]]
[:test/route9 ["topics" handler]]
[:bookmarks ["bookmarks" handler {:test/route10 ["followers" handler]}]]
[:test/route15 ["devices" handler
[[:test/route35 [true handler]]
[:client-id [true handler
{:test/route49 ["reset-password" handler]}]]]]]
[:test/route22 ["device-errors" handler]]
[:test/route24 ["usage-stats" handler]]
[:claim-device ["claim-device" handler {:test/route26 [true handler]}]]
[:test/route31 ["owned-orgs" handler]]
[:bookmark ["bookmark" handler {:test/route33 [true handler]}]]
[:test/route52 ["orgs" handler]]
[:test/route43 ["api-key" handler]]
[:test/route56 ["bookmarks" handler]]]]}]]
[:search ["search" handler
{:topics ["topics" handler {:test/route6 [true handler]}]}]]
[:test/route55 ["orgs" handler
[[:test/route42 [true handler
[[:test/route37 ["devices" handler
[[:test/route13 [true handler]]]]]
[:test/route12 ["usage-stats" handler]]
[:test/route19 ["invitations" handler]]
[:test/route38 ["members" handler
[[:test/route34 [true handler]]]]]
[:test/route17 ["errors" handler]]
[:confirm-membership ["confirm-membership" handler
{:test/route46 [true handler]}]]
[:test/route57 ["topics" handler]]]]]]]]
[:messages ["messages" handler
[[:user ["user" handler {:test/route14 [true handler]}]]
[:device ["device" handler {:test/route30 [true handler]}]]
[:topic ["topic" handler {:test/route48 [true handler]}]]]]]
[:test/route54 ["topics" handler
[[:test/route32 [true handler]]]]]
[:test/route41 ["whoami" handler]]
[:test/route51 ["login" handler]]]]
:v2 ["v2" handler
[[:test/route1 ["whoami" handler]]
[:users ["users" handler
{:test/route45 [true handler
[[:test/route2 ["datasets" handler]]
[:test/route25 ["devices" handler]]
[:test/route54 ["topics" handler
[[:test/route29 ["bulk" handler]]]]]]]}]]
[:public ["public" handler
[[:projects ["projects" handler
{:test/route27 [true handler
[[:test/route3 ["datasets" handler]]]]}]]
[:datasets ["datasets" handler
{:test/route28 [true handler]}]]
[:messages ["messages" handler
{:dataset ["dataset" handler
{:test/route53 [true handler]}]}]]]]]
[:datasets ["datasets" handler
{:test/route11 [true handler]}]]
[:test/route23 ["login" handler]]
[:orgs ["orgs" handler
{:org-id [true handler
{:test/route40 ["topics" handler]}]}]]
[:test/route44 ["schemas" handler]]
[:topics ["topics" handler
{:test/route47 [true handler]}]]
[:test/route50 ["topics" handler]]]]}]))
(comment
(janus/identify opensensors-janus-routes "/v2/public/messages/dataset/987")
(-> opensensors-janus-routes
(janus/identify "/v2/public/messages/dataset/987")
(janus/dispatch* "/v2/public/messages/dataset/987"))
((-> (janus.ring/make-dispatcher)
(janus.ring/wrap-identify opensensors-janus-routes))
{:uri "/v2/public/messages/dataset/987"}))
(def opensensors-pedestal-routes
(map-tree/router
(table/table-routes
@ -562,6 +649,7 @@
ataraxy-f (partial ataraxy/matches opensensors-ataraxy-routes)
compojure-f opensensors-compojure-routes
pedestal-f (partial pedestal/find-route opensensors-pedestal-routes)
janus-f (-> (janus.ring/make-dispatcher) (janus.ring/wrap-identify opensensors-janus-routes))
b! (partial bench!! routes (fn [path] {:request-method :get, :uri path, :path-info path}) true)]
;; 2538ns
@ -621,7 +709,10 @@
(b! "bidi" bidi-f)
;; 19688ns
(b! "ataraxy" ataraxy-f)))
(b! "ataraxy" ataraxy-f)
;; 7550ns
(b! "janus" janus-f)))
(comment
(bench-rest!))

View file

@ -1,4 +1,4 @@
(defproject metosin/reitit-parent "0.3.10"
(defproject metosin/reitit-parent "0.4.2"
:description "Snappy data-driven router for Clojure(Script)"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"
@ -12,29 +12,32 @@
:url "https://github.com/metosin/reitit"}
;; TODO: need to verify that the code actually worked with Java1.8, see #242
:javac-options ["-Xlint:unchecked" "-target" "1.8" "-source" "1.8"]
:managed-dependencies [[metosin/reitit "0.3.10"]
[metosin/reitit-core "0.3.10"]
[metosin/reitit-dev "0.3.10"]
[metosin/reitit-spec "0.3.10"]
[metosin/reitit-malli "0.3.10"]
[metosin/reitit-schema "0.3.10"]
[metosin/reitit-ring "0.3.10"]
[metosin/reitit-middleware "0.3.10"]
[metosin/reitit-http "0.3.10"]
[metosin/reitit-interceptors "0.3.10"]
[metosin/reitit-swagger "0.3.10"]
[metosin/reitit-swagger-ui "0.3.10"]
[metosin/reitit-frontend "0.3.10"]
[metosin/reitit-sieppari "0.3.10"]
[metosin/reitit-pedestal "0.3.10"]
:managed-dependencies [[metosin/reitit "0.4.2"]
[metosin/reitit-core "0.4.2"]
[metosin/reitit-dev "0.4.2"]
[metosin/reitit-spec "0.4.2"]
[metosin/reitit-malli "0.4.2"]
[metosin/reitit-schema "0.4.2"]
[metosin/reitit-ring "0.4.2"]
[metosin/reitit-middleware "0.4.2"]
[metosin/reitit-http "0.4.2"]
[metosin/reitit-interceptors "0.4.2"]
[metosin/reitit-swagger "0.4.2"]
[metosin/reitit-swagger-ui "0.4.2"]
[metosin/reitit-frontend "0.4.2"]
[metosin/reitit-sieppari "0.4.2"]
[metosin/reitit-pedestal "0.4.2"]
[metosin/ring-swagger-ui "3.24.3"]
[metosin/spec-tools "0.10.0"]
[metosin/schema-tools "0.12.1"]
[metosin/muuntaja "0.6.6"]
[metosin/jsonista "0.2.5"]
[metosin/sieppari "0.0.0-alpha7"]
[metosin/sieppari "0.0.0-alpha8"]
[metosin/malli "0.0.1-20200108.194558-11"]
;; https://clojureverse.org/t/depending-on-the-right-versions-of-jackson-libraries/5111
[com.fasterxml.jackson.core/jackson-core "2.10.0"]
[meta-merge "1.0.0"]
[fipp "0.6.22" :exclusions [org.clojure/core.rrb-vector]]
[expound "0.8.4"]
@ -130,7 +133,8 @@
[aleph "0.4.6"]
[ring/ring-defaults "0.3.2"]
[ataraxy "0.4.2"]
[bidi "2.1.6"]]}
[bidi "2.1.6"]
[janus "1.3.0"]]}
:analyze {:jvm-opts ^:replace ["-server"
"-Dclojure.compiler.direct-linking=true"
"-XX:+PrintCompilation"