This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-11-21
Channels
- # beginners (5)
- # boot (15)
- # capetown (1)
- # chestnut (2)
- # cljs-dev (9)
- # cljsjs (3)
- # cljsrn (1)
- # clojure (190)
- # clojure-brasil (2)
- # clojure-greece (14)
- # clojure-italy (3)
- # clojure-poland (8)
- # clojure-romania (1)
- # clojure-russia (2)
- # clojure-serbia (3)
- # clojure-spec (38)
- # clojure-uk (98)
- # clojure-ukraine (2)
- # clojurescript (65)
- # clojurex (1)
- # core-async (16)
- # cursive (16)
- # datomic (3)
- # defnpodcast (7)
- # emacs (11)
- # funcool (2)
- # hoplon (16)
- # jobs (1)
- # leiningen (4)
- # lumo (9)
- # off-topic (2)
- # om (1)
- # other-languages (1)
- # protorepl (1)
- # re-frame (50)
- # reagent (16)
- # reitit (32)
- # remote-jobs (1)
- # rum (1)
- # shadow-cljs (73)
- # spacemacs (36)
- # specter (21)
- # sql (6)
- # unrepl (107)
- # untangled (4)
o/ Thanks for writing reitit, I like it! I might come and bug you now with questions about coercion and like. You have been warned! 🙂
Glad you like it! Question are good, we'll try to make awesome docs with a FAQ. Need the questions first ;)
Quick status update for 0.1.0:
* replace prefix-tree-router with segment-router (correctness & faster)
* reitit-schema
(the schema coercion module)
* more tests
Next steps:
* extra stuff for the data-driven middleware / interceptors (written as issues)
* reitit-cljs
? (extract from the ongoing projects, with the lovely routing controllers)
* reitit-openapi
(swagger-stuff, should be trivial)
* reitit-interceptor
(all the mw stuff ported to interceptor-model)
the routing is already quite fast, but with the new segment-router, it’s 30% faster. Which is cool imo, if not useful 🙂
as I mentioned in the reddit thread, it seems like you could just add the additional keys compojure-api style
["/api" {:middleware [[wrap :api]]}
["/subtract" {:get handler
:query-params [x :- Long, {y :- Long 1}]
:return Long
:name ::subtruct}]
the nice part about this is that you could start with plain reitit and then add reitit-api on top of that
Currently, the coercion module uses the ring-swagger/openapi format for the routes. So, you can write the example as:
(require '[reitit.ring :as ring])
(require '[reitit.ring.coercion :as coercion])
(require '[reitit.ring.coercion.schema :as schema])
(def app
(ring/ring-handler
(ring/router
["/api" {:middleware [[wrap :api]]}
["/subtract" {:get handler
:parameters {:query {:x Long, :y Long}}
:responses {200 {:schema Long}}
:name ::subtruct}]]
{:data {:middleware [coercion/gen-wrap-coerce-parameters
coercion/gen-wrap-coerce-response]
:coercion schema/coercion}})))
to support :query-params [x :- Long, {y :- Long 1}]
format - the whole endpoint would need to be wrapped into a unevaluated form. As the y
and x
would fail otherwise.
To support the fnk
notation, we could extract the schema form the handler. So this would work:
(require '[reitit.ring :as ring])
(require '[reitit.ring.coercion :as coercion])
(require '[reitit.ring.coercion.schema :as schema])
(require '[plumbing.core :refer [fnk]])
(def app
(ring/ring-handler
(ring/router
["/api" {:middleware [[wrap :api]]}
["/subtract" {:get (fnk [[:parameters [:query x :- Long, y :- Long]]]
{:status 200, :body (+ x y)})
:responses {200 {:schema Long}}
:name ::subtruct}]]
{:data {:middleware [coercion/gen-wrap-coerce-parameters
coercion/gen-wrap-coerce-response]
:coercion schema/coercion}})))
this is just as readable as schema syntax in my opinion:
:parameters {:query {:x Long, :y Long}}
:responses {200 {:schema Long}
I’m planning on using spec to make the route data syntax sane: different parts of the system (router, middleware, interceptors) can tell a spec about the route data requirements they have. The partial specs will be merged to get the overall route data spec. All route data is validated against this at router creation time -> will notify the user if there are typos in the keys, like figwheel does.
If you have a key :auth
in a route, which doesn’t have a authorize-middleware
(telling it’s interested in the :auth
key), user will get a warning of unhandled key.
good thing is that we know the whole mw/interceptor chain for each route, and the mws are just data, so we can optimize things.
e.g. apply parse-request-body
for the whole router, but unmount it for all routes that are not interested in the :body
parameters.
and it looks like applying middleware selectively to specific branches becomes much cleaner than when using compojure
To get real benefits of data-driven middleware, middleware should be wrapped into Middleware
records.
at least, all mw should have a unique :name
. There will be an Inventory
api in reitit: to list all things registered: schemas, specs, mw, endpoints etc.
There are similar thoughts in the Macchiato: https://github.com/macchiato-framework/macchiato-core/issues/9
But, it would be lovely to need a CORS Mw, and have in packaged so that when asking from an endpoint about its mounted mw, it would say [#Middleware{:name ::cors, :description "adding cors"}]
instead of [#object[a.b.c 0x79e89cd2 “a.b.c$cors-middlware@79e89cd2”]