It's possible to put the :keys keyword in the namespace of the keys one likes to destructure. With that one can use symbols in the vector again. One advantage of having symbols is, that Cursive grays them out if not used. I found two occurrences of unused destructured keys.
30 KiB
Reitit CHANGELOG
We use Break Versioning. The version numbers follow a <major>.<minor>.<patch> scheme with the following intent:
| Bump | Intent |
|---|---|
major |
Major breaking changes -- check the changelog for details. |
minor |
Minor breaking changes -- check the changelog for details. |
patch |
No breaking changes, ever!! |
-SNAPSHOT versions are preview versions for upcoming releases.
0.3.9 (2019-06-16)
reitit-ring
- Added async support for
default-options-handleronreitit-ring, fixes #293
0.3.8 (2019-06-15)
- Updated dependencies:
[metosin/schema-tools "0.12.0"] is available but we use "0.11.0"
[metosin/spec-tools "0.9.3"] is available but we use "0.9.2"
[metosin/jsonista "0.2.3"] is available but we use "0.2.2"
reitit-core
-
Schema coercion supports transformtatins from keywords->clojure, via schema-tools.
-
Add support for explixit selection of router path-parameter
:syntax, fixes #276
(require '[reitit.core :as r])
;; default
(-> (r/router
["http://localhost:8080/api/user/{id}" ::user-by-id])
(r/match-by-path "http://localhost:8080/api/user/123"))
;#Match{:template "http://localhost:8080/api/user/{id}",
; :data {:name :user/user-by-id},
; :result nil,
; :path-params {:id "123", :8080 ":8080"},
; :path "http://localhost:8080/api/user/123"}
;; just bracket-syntax
(-> (r/router
["http://localhost:8080/api/user/{id}" ::user-by-id]
{:syntax :bracket})
(r/match-by-path "http://localhost:8080/api/user/123"))
;#Match{:template "http://localhost:8080/api/user/{id}",
; :data {:name :user/user-by-id},
; :result nil,
; :path-params {:id "123"},
; :path "http://localhost:8080/api/user/123"}
0.3.7 (2019-05-25)
reitit-pedestal
- Fixed Pedestal Interceptor coercion bug, see #285.
0.3.6 (2019-05-23)
- Fixed a zillion typos in docs by Marcus Spiegel.
reitit-ring
- Fix on
reitit.ring/create-default-handlerto support overriding just some handlers, fixes #283, by Daniel Sunnerek.
0.3.5 (2019-05-22)
reitit-core
- MAJOR: Fix bug in Java Trie (since 0.3.0!), which made invalid path parameter parsing in concurrent requests. All Trie implementation classes are final from now on.
0.3.4 (2019-05-20)
reitit-core
- Spec problems are reported correctly in coercion by Kevin W. van Rooijen.
0.3.3 (2019-05-16)
- Better error messages on route data merge error:
(ns user
(:require [reitit.core :as r]
[schema.core :as s]
[reitit.dev.pretty :as pretty]))
(r/router
["/kikka"
{:parameters {:body {:id s/Str}}}
["/kakka"
{:parameters {:body [s/Str]}}]]
{:exception pretty/exception})
; -- Router creation failed -------------------------------------------- user:7 --
;
; Error merging route-data:
;
; -- On route -----------------------
;
; /kikka/kakka
;
; -- Exception ----------------------
;
; Don't know how to create ISeq from: java.lang.Class
;
; {:parameters {:body {:id java.lang.String}}}
;
; {:parameters {:body [java.lang.String]}}
;
; https://cljdoc.org/d/metosin/reitit/CURRENT/doc/basics/route-data
;
; --------------------------------------------------------------------------------
0.3.2 (2019-05-13)
- Updated dependencies:
[metosin/spec-tools "0.9.2"] is available but we use "0.9.0"
[metosin/muuntaja "0.6.4"] is available but we use "0.6.3"
[fipp "0.6.18"] is available but we use "0.6.17"
[lambdaisland/deep-diff "0.0-47"] is available but we use "0.0-25"
- Updated guides on Error Messages & Route-data Validation
reitit-core
- new options
:reitit.spec/wrapto wrap top-level route data specs when spec validation is enabled. Usingspec-tools.spell/closedcloses top-level specs.- Updated swagger-examples to easily enable closed spec validation
(require '[reitit.core :as r])
(require '[reitit.spec :as rs])
(require '[reitit.dev.pretty :as pretty)
(require '[spec-tools.spell :as spell])
(require '[clojure.spec.alpha :as s])
(s/def ::description string?)
(r/router
["/api" {:summary "kikka"}]
{:validate rs/validate
:spec (s/merge ::rs/default-data (s/keys :req-un [::description]))
::rs/wrap spell/closed
:exception pretty/exception})
reitit-frontend
- add support for html5 links inside Shadow DOM by Antti Leppänen.
- lot's of React-router examples ported in, thanks to Valtteri Harmainen
reitit.pedestal
- Automatically coerce Sieppari-style 1-arity
:errorhandlers into Pedestal-style 2-arity:errorhandlers. Thanks to Mathieu MARCHANDISE.
reitit-middleware
reitit.ring.middleware.dev/print-request-diffsprints also response diffs.
0.3.1 (2019-03-18)
- Recompiled with Java8 as target, fixes #241.
0.3.0 (2019-03-17)
reitit-core
-
welcome new wildcard routing!
- optional bracket-syntax with parameters
"/user/:user-id"="/user/{user-id}""/assets/*asset"="/assets/{*asset}
- enabling qualified parameters
"/user/{my.user/id}/{my.order/id}"
- parameters don't have to span whole segments
"/file-:id/topics"(free start, ends at slash)"/file-{name}.html"(free start & end)
- backed by a new
:trie-router, replacing:segment-router- up to 2x faster on the JVM
- optional bracket-syntax with parameters
-
BREAKING:
reitit.spec/validate-spec!has been renamed tovalidate -
With
clojure.speccoercion, values flow through bothst/coerce&st/conformyielding better error messages. Original issue in compojure-api.
reitit-dev
- new module for friendly router creation time exception handling
Conflicting paths
(require '[reitit.core :as r])
(require '[reitit.dev.pretty :as pretty])
(r/router
[["/ping"]
["/:user-id/orders"]
["/bulk/:bulk-id"]
["/public/*path"]
["/:version/status"]]
{:exception pretty/exception})
Route data error
(require '[reitit.spec :as spec])
(require '[clojure.spec.alpha :as s])
(s/def ::role #{:admin :user})
(s/def ::roles (s/coll-of ::role :into #{}))
(r/router
["/api/admin" {::roles #{:adminz}}]
{:validate spec/validate
:exception pretty/exception})
reitit-frontend
- Frontend controllers redesigned
- Controller
:paramsfunction has been deprecated - Controller
:identityfunction works the same as:params - New
:parametersoption can be used to declare which parameters controller is interested in, as data, which should cover most use cases:{:start start-fn, :parameters {:path [:foo-id]}}
- Controller
- Ensure HTML5 History routing works with IE11
reitit-ring
- Allow Middleware to compile to
nilwith Middleware Registries, fixes to #216. - BREAKING:
reitit.ring.spec/validate-spec!has been renamed tovalidate
reitit-http
- Allow Interceptors to compile to
nilwith Interceptor Registries, related to #216. - BREAKING:
reitit.http.spec/validate-spec!has been renamed tovalidate
Dependencies
- updated:
[metosin/spec-tools "0.9.0"] is available but we use "0.8.3"
[metosin/schema-tools "0.11.0"] is available but we use "0.10.5"
0.2.13 (2019-01-26)
- Don't throw
StringIndexOutOfBoundsExceptionwith empty path lookup on wildcard paths, fixes #209
0.2.12 (2019-01-18)
- fixed reflection & boxed math warnings, fixes #207
- fixed arity-error on default routes with
reitit-ring&reitit-httpwhen:inject-router?set tofalse.
0.2.11 (2019-01-17)
- new guide on pretty printing spec coercion errors with expound, fixes #153.
reitit-core
reitit.core/Expandcan be extended, fixes #201.- new snappy Java-backed
SegmentTrierouting algorithm and data structure backingreitit.core/segment-router, making wildcard routing 2x faster on the JVM reitit.core/linear-routeruses the segment router behind the scenes, 2-4x faster on the JVM too.
reitit-ring
- new options
:inject-match?and:inject-router?onreitit.ring/ring-handlerto optionally not to injectRouterandMatchinto the request. See performance guide for details.
reitit-http
- new options
:inject-match?and:inject-router?onreitit.http/ring-handlerandreitit.http/routing-interceptorto optionally not to injectRouterandMatchinto the request. See performance guide for details.
dependencies
- updated:
[metosin/spec-tools "0.8.3"] is available but we use "0.8.2"
0.2.10 (2018-12-30)
reitit-core
segment-routerdoesn't accept empty segments as path-parameters, fixes #181.- path-params are decoded correctly with
r/match-by-name, fixes #192. - new
:quarantine-router, which is uses by default if there are any path conflicts: uses internally:mixed-routerfor non-conflicting routes and:linear-routerfor conflicting routes.
(-> [["/joulu/kinkku"] ;; linear-router
["/joulu/:torttu"] ;; linear-router
["/tonttu/:id"] ;; segment-router
["/manna/puuro"] ;; lookup-router
["/sinappi/silli"]] ;; lookup-router
(r/router {:conflicts nil})
(r/router-name))
; => :quarantine-router
reitit.interceptor/transform-butlasthelper to transform the interceptor chains (last one is usually the handler).
reitit-middleware
reitit.ring.middleware.dev/print-request-diffsmiddleware transformation function to print out request diffs between middleware to the console- read the docs
- see example app
reitit-interceptors
reitit.http.interceptors.dev/print-context-diffsinterceptor transformation function to print out context diffs between interceptor steps to the console:- read the docs
- see example app
reitit-sieppari
- New version of Sieppari allows interceptors to run on ClojureScript too.
reitit-pedestal
dependencies
- updated:
[metosin/muuntaja "0.6.3"] is available but we use "0.6.1"
[metosin/sieppari "0.0.0-alpha6"] is available but we use "0.0.0-alpha7"
0.2.9 (2018-11-21)
reitit-spec
- support for vector data-specs for request & response parameters by Heikki Hämäläinen.
0.2.8 (2018-11-18)
reitit-core
- Added support for composing middleware & interceptor transformations, fixes #167.
reitit-spec
- Spec problems are exposed as-is into request & response coercion errors, enabling pretty-printers like expound to be used:
(require '[reitit.ring :as ring])
(require '[reitit.ring.middleware.exception :as exception])
(require '[reitit.ring.coercion :as coercion])
(require '[expound.alpha :as expound])
(defn coercion-error-handler [status]
(let [printer (expound/custom-printer {:theme :figwheel-theme, :print-specs? false})
handler (exception/create-coercion-handler status)]
(fn [exception request]
(printer (-> exception ex-data :problems))
(handler exception request))))
(def app
(ring/ring-handler
(ring/router
["/plus"
{:get
{:parameters {:query {:x int?, :y int?}}
:responses {200 {:body {:total pos-int?}}}
:handler (fn [{{{:keys [x y]} :query} :parameters}]
{:status 200, :body {:total (+ x y)}})}}]
{:data {:coercion reitit.coercion.spec/coercion
:middleware [(exception/create-exception-middleware
(merge
exception/default-handlers
{:reitit.coercion/request-coercion (coercion-error-handler 400)
:reitit.coercion/response-coercion (coercion-error-handler 500)}))
coercion/coerce-request-middleware
coercion/coerce-response-middleware]}})))
(app
{:uri "/plus"
:request-method :get
:query-params {"x" "1", "y" "fail"}})
(app
{:uri "/plus"
:request-method :get
:query-params {"x" "1", "y" "-2"}})
reitit-swagger
create-swagger-handlersupport now 3-arity ring-async, thanks to Miloslav Nenadál
0.2.7 (2018-11-11)
reitit-spec
-
updated deps:
[metosin/spec-tools "0.8.2"] is available but we use "0.8.1"
0.2.6 (2018-11-09)
reitit-core
- Faster path-parameter decoding: doing less work when parameters don't need decoding. Wildcard-routing is now 10-15% faster in perf tests (opensensors & github api).
- Fixed a ClojureScript compiler warning about private var usage. #169
reitit-ring
-
redirect-trailing-slash-handlercan strip multiple slashes from end of the uri, by Hannu Hartikainen. -
Fixed a ClojureScript compiler warning about
satisfies?being a macro. -
updated deps:
[ring "1.7.1"] is available but we use "1.7.0"
reitit-spec
- updated deps:
[metosin/spec-tools "0.8.1"] is available but we use "0.8.0"
reitit-schema
- updated deps:
[metosin/schema-tools "0.10.5"] is available but we use "0.10.4"
reitit-sieppari
- updated deps:
[metosin/sieppari "0.0.0-alpha6"] is available but we use "0.0.0-alpha5"
0.2.5 (2018-10-30)
reitit-ring
- router is injected into request also in the default branch
- new
reitit.ring/redirect-trailing-slash-handlerto handle trailing slashes with style!
(require '[reitit.ring :as ring])
(def app
(ring/ring-handler
(ring/router
[["/ping" (constantly {:status 200, :body ""})]
["/pong/" (constantly {:status 200, :body ""})]])
(ring/redirect-trailing-slash-handler)))
(app {:uri "/ping/"})
; {:status 308, :headers {"Location" "/ping"}, :body ""}
(app {:uri "/pong"})
; {:status 308, :headers {"Location" "/pong/"}, :body ""}
- updated deps:
[ring/ring-core "1.7.1"] is available but we use "1.7.0"
reitit-http
- router is injected into request also in the default branch
0.2.4 (2018-10-21)
reitit-ring
- New option
:not-found-handlerinreitit.ring/create-resource-handlerto set how 404 is handled. Fixes #89, thanks to valerauko.
reitit-spec
-
Latest features from spec-tools
- Swagger enhancements
- Better spec coercion via
st/coerceusing spec walking & inference: many simple specs (core predicates,spec-tools.core/spec,s/and,s/or,s/coll-of,s/keys,s/map-of,s/nillableands/every) can be transformed without needing spec to be wrapped. Fallbacks to old conformed based approach. - example app.
-
updated deps:
[metosin/spec-tools "0.8.0"] is available but we use "0.7.1"
0.2.3 (2018-09-24)
reitit-ring
ring-handlertakes optionally a 3rd argument, an options map which can be used to se top-level middleware, applied before any routing is done:
(require '[reitit.ring :as ring])
(defn wrap [handler id]
(fn [request]
(handler (update request ::acc (fnil conj []) id))))
(defn handler [{::keys [acc]}]
{:status 200, :body (conj acc :handler)})
(def app
(ring/ring-handler
(ring/router
["/api" {:middleware [[mw :api]]}
["/get" {:get handler}]])
(ring/create-default-handler)
{:middleware [[mw :top]]}))
(app {:request-method :get, :uri "/api/get"})
; {:status 200, :body [:top :api :ok]}
(require '[reitit.core :as r])
(-> app (ring/get-router))
; #object[reitit.core$single_static_path_router]
-
:optionsrequests are served for all routes by default with 200 OK to better support things like CORS- the default handler is not documented in Swagger
- new router option
:reitit.ring/default-options-handlerto change this behavior. Settingnildisables this.
-
updated deps:
[ring/ring-core "1.7.0"] is available but we use "1.6.3"
reitit-http
:optionsrequests are served for all routes by default with 200 OK to better support things like CORS- the default handler is not documented in Swagger
- new router option
:reitit.http/default-options-handlerto change this behavior. Settingnildisables this.
reitit-middleware
-
fix
reitit.ring.middleware.parameters/parameters-middleware -
updated deps:
[metosin/muuntaja "0.6.1"] is available but we use "0.6.0"
reitit-swagger-ui
- updated deps:
[metosin/jsonista "0.2.2"] is available but we use "0.2.1"
0.2.2 (2018-09-09)
- better documentation for interceptors
- sample apps:
reitit-middleware
- new middleware
reitit.ring.middleware.parameters/parameters-middlewareto wrap query & form params.
reitit-interceptors
- new module like
reitit-middlewarebut for interceptors. See the Docs.
0.2.1 (2018-09-04)
reitit-schema
- updated deps:
[metosin/schema-tools "0.10.4"] is available but we use "0.10.3"
reitit-middleware
- updated deps:
[metosin/muuntaja "0.6.0"] is available but we use "0.6.0-alpha5"
0.2.0 (2018-09-03)
Sample apps demonstrating the current status of reitit:
reitit-ringwith coercion, swagger and default middlewarereitit-frontend, the easy wayreitit-frontentwith Keechma-style controllersreitit-httpwith Pedestalreitit-httpwith Sieppari
reitit-core
- BREAKING: the router option key to extract body format has been renamed:
:extract-request-format=>:reitit.coercion/extract-request-format- should only concern you if you are not using Muuntaja.
- the
r/routesreturns just the path + data tuples as documented, not the compiled route results. To get the compiled results, user/compiled-routesinstead. - new faster and more correct encoders and decoders for query & path params.
- all path-parameters are now decoded correctly with
reitit.impl/url-decode, thanks to Matthew Davidson! - query-parameters are encoded with
reitit.impl/form-encode, so spaces are+instead of%20.
- all path-parameters are now decoded correctly with
- correctly read
:headerparams from request:headers, not:header-params - welcome route name conflict resolution! If router has routes with same names, router can't be created. fix 'em.
- sequential child routes are allowed, enabling this:
(-> ["/api"
(for [i (range 4)]
[(str "/" i)])]
(r/router)
(r/routes))
;[["/api/0" {}]
; ["/api/1" {}]
; ["/api/2" {}]
; ["/api/3" {}]]
- A Guide to compose routers
- Welcome Middleware and Intercetor Registries!
(require '[reitit.ring :as ring])
(require '[reitit.middleware :as middleware])
(defn wrap-bonus [handler value]
(fn [request]
(handler (update request :bonus (fnil + 0) value))))
(def app
(ring/ring-handler
(ring/router
["/api" {:middleware [[:bonus 20]]}
["/bonus" {:middleware [:bonus10]
:get (fn [{:keys [bonus]}]
{:status 200, :body {:bonus bonus}})}]]
{::middleware/registry {:bonus wrap-bonus
:bonus10 [:bonus 10]}})))
(app {:request-method :get, :uri "/api/bonus"})
; {:status 200, :body {:bonus 30}}
reitit-swagger
- In case of just one swagger api per router, the swagger api doesn't have to identified, so this works now:
(require '[reitit.ring :as ring])
(require '[reitit.swagger :as swagger])
(require '[reitit.swagger-ui :as swagger-ui])
(ring/ring-handler
(ring/router
[["/ping"
{:get (fn [_] {:status 200, :body "pong"})}]
["/swagger.json"
{:get {:no-doc true
:handler (swagger/create-swagger-handler)}}]])
(swagger-ui/create-swagger-ui-handler {:path "/"}))
reitit-middleware
- A new module with common data-driven middleware: exception handling, content negotiation & multipart requests. See the docs.
reitit-swagger-ui
- BREAKING: pass swagger-ui
:configas-is (instead of mixed-casing keys) to swagger-ui, fixes #109:- see docs for available parameters.
(swagger-ui/create-swagger-ui-handler
{:path "/"
:url "/api/swagger.json"
:config {:jsonEditor true
:validatorUrl nil}})
reitit-frontend
- new module for frontend-routing. See docs for details.
0.1.3 (2018-6-25)
reitit-core
reitit.coercion/coerce!coerced all parameters found in match, e.g. injecting in:query-parametersintoMatchwith coerce those too if:querycoercion is defined.- if response coercion is not defined for a response status, response is still returned
spec-tools.data-spec/maybecan be used in spec-coercion.
(def router
(reitit.core/router
["/spec" {:coercion reitit.coercion.spec/coercion}
["/:number/:keyword" {:parameters {:path {:number int?
:keyword keyword?}
:query (ds/maybe {:int int?})}}]]
{:compile reitit.coercion/compile-request-coercers}))
(-> (reitit.core/match-by-path router "/spec/10/kikka")
(assoc :query-params {:int "10"})
(reitit.coercion/coerce!))
; {:path {:number 10, :keyword :kikka}
; :query {:int 10}}
reitit.core/match->pathto create full paths from match, including the query parameters:
(require '[reitit.core :as r])
(-> (r/router ["/:a/:b" ::route])
(r/match-by-name! ::route {:a "olipa", :b "kerran"})
(r/match->path))
; "/olipa/kerran"
(-> (r/router ["/:a/:b" ::route])
(r/match-by-name! ::route {:a "olipa", :b "kerran"})
(r/match->path {:iso "pöriläinen"}))
; "/olipa/kerran?iso=p%C3%B6ril%C3%A4inen"
reitit-spec
[metosin/spec-tools "0.7.1"]with swagger generation enhancements, see the CHANGELOG- if response coercion is not defined for a response status, no
:schemais not emitted. - updated dependencies:
[metosin/spec-tools "0.7.1"] is available but we use "0.7.0"
reitit-schema
- if response coercion is not defined for a response status, no
:schemais not emitted.
0.1.2 (2018-6-6)
reitit-core
- Better handling of
nilin route syntax:- explicit
nilafter path string is always handled asnilroute nilas path string causes the whole route to benilnilas child route is stripped away
- explicit
(testing "nil routes are stripped"
(is (= [] (r/routes (r/router nil))))
(is (= [] (r/routes (r/router [nil ["/ping"]]))))
(is (= [] (r/routes (r/router [nil [nil] [[nil nil nil]]]))))
(is (= [] (r/routes (r/router ["/ping" [nil "/pong"]])))))
reitit-ring
- Use HTTP redirect (302) with index-files in
reitit.ring/create-resource-handler. reitit.ring/create-default-handlernow conforms to RING Spec, Fixes #83
reitit-schema
- updated dependencies:
[metosin/schema-tools "0.10.3"] is available but we use "0.10.2"
reitit-swagger
- Fix Swagger-paths, by Kirill Chernyshov.
reitit-swagger-ui
-
Use HTTP redirect (302) with index-files in
reitit.swagger-ui/create-swagger-ui-handler. -
updated dependencies:
[metosin/jsonista "0.2.1"] is available but we use "0.2.0"
0.1.1 (2018-5-20)
reitit-core
linear-routernow works with unnamed catch-all parameters, e.g."/files/*"match-by-pathencodes parameters into strings using (internal)reitit.impl/IntoStringprotocol. Handles all of: strings, numbers, keywords, booleans, objects. Fixes #75.
(require '[reitit.core :as r])
(r/match-by-name
(r/router
["/coffee/:type" ::coffee])
::coffee
{:type :luwak})
;#Match{:template "/coffee/:type",
; :data {:name :user/coffee},
; :result nil,
; :path-params {:type "luwak"},
; :path "/coffee/luwak"}
reitit-ring
-
reitit.ring/default-handlernow works correctly with async ring -
new helper
reitit.ring/routerto compose routes outside of a router. -
reitit.ring/create-resource-handlerfunction to serve static routes. See docs. -
new dependencies:
[ring/ring-core "1.6.3"]
reitit-swagger
- New module to produce swagger-docs from routing tree, including
Coerciondefinitions. Works with both middleware & interceptors and Schema & Spec. See docs and example project.
reitit-swagger-ui
New module to server pre-integrated Swagger-ui. See docs.
- new dependencies:
[metosin/jsonista "0.2.0"]
[metosin/ring-swagger-ui "2.2.10"]
dependencies
[metosin/spec-tools "0.7.0"] is available but we use "0.6.1"
[metosin/schema-tools "0.10.2"] is available but we use "0.10.1"
0.1.0 (2018-2-19)
- First release
