Fork me on GitHub
#reitit
<
2018-05-31
>
ikitommi07:05:26

Is someone using the route-data validation? Checked how to integrate spec-tools + spell-spec together, planning to port all middleware, interceptor and feature specs into data-specs and get spell-spec for free. Not 100% it works, but will try.

ikitommi07:05:04

I think there could be reitit-dev module, with expound and spell-spec pre-integrated. could contains a function to wrap any router, injecting the needed options to get the data validation enabled easily. and maybe serve the routes to a dev-ui/visualization.

ikitommi07:05:54

kindof like swagger-ui, but so much better.

conan10:05:01

I'm struggling with another spec validation problem. The first request sent that routes via reitit fails the :ring/request spec from ring-spec because the request map that gets passed to it contains the keys :body and :query-string with nil values, but these keys are not nilable. Any idea how these keys find their way into the request map? This doesn't seem to happen if the requests are not routed via reitit - my top-level handler is created using (rr/ring-handler (rr/router ...))

conan10:05:16

Here's the error (via expound):

Call to #'hanabi.web/initialise did not conform to spec:
web.clj:181

-- Spec failed --------------------

Function arguments

  ({:reitit.core/match ...,
    :reitit.core/router ...,
    :remote-addr ...,
    :params ...,
    :headers ...,
    :async-channel ...,
    :server-port ...,
    :content-length ...,
    :form-params ...,
    :websocket? ...,
    :web/session ...,
    :query-params ...,
    :content-type ...,
    :character-encoding ...,
    :uri ...,
    :server-name ...,
    :query-string ...,
    :path-params ...,
    :body nil,
          ^^^
    :scheme ...,
    :request-method ...})

should satisfy

  #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x765709fc "clojure.spec.alpha$regex_spec_impl$reify__2436@765709fc"]

-- Relevant specs -------

:ring.request/body:
  :clojure.spec.alpha/unknown
:ring/request:
  (clojure.spec.alpha/keys
   :req-un
   [:ring.request/server-port
    :ring.request/server-name
    :ring.request/remote-addr
    :ring.request/uri
    :ring.request/scheme
    :ring.request/protocol
    :ring.request/headers
    :ring.request/request-method]
   :opt-un
   [:ring.request/query-string :ring.request/body])
:web.ring/request:
  (clojure.spec.alpha/merge
   :ring/request
   (clojure.spec.alpha/keys
    :req
    [:web/session]
    :req-un
    [:web.ring.request/edn-params]))

-- Spec failed --------------------

Function arguments

  ({:reitit.core/match ...,
    :reitit.core/router ...,
    :remote-addr ...,
    :params ...,
    :headers ...,
    :async-channel ...,
    :server-port ...,
    :content-length ...,
    :form-params ...,
    :websocket? ...,
    :web/session ...,
    :query-params ...,
    :content-type ...,
    :character-encoding ...,
    :uri ...,
    :server-name ...,
    :query-string nil,
                  ^^^
    :path-params ...,
    :body ...,
    :scheme ...,
    :request-method ...})

should satisfy

  #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x765709fc "clojure.spec.alpha$regex_spec_impl$reify__2436@765709fc"]

-- Relevant specs -------

:ring.request/query-string:
  :clojure.spec.alpha/unknown
:ring/request:
  (clojure.spec.alpha/keys
   :req-un
   [:ring.request/server-port
    :ring.request/server-name
    :ring.request/remote-addr
    :ring.request/uri
    :ring.request/scheme
    :ring.request/protocol
    :ring.request/headers
    :ring.request/request-method]
   :opt-un
   [:ring.request/query-string :ring.request/body])
:web.ring/request:
  (clojure.spec.alpha/merge
   :ring/request
   (clojure.spec.alpha/keys
    :req
    [:web/session]
    :req-un
    [:web.ring.request/edn-params]))

-------------------------
Detected 2 errors

ikitommi10:05:00

query-string is parsed by a external middleware, like ring.middleware.params/wrap-params, :body is nil after it’s consumed by the body-formatter like muuntaja.middleware/wrap-format.

conan10:05:23

ok, so these middlewares are not ring-compatible?

ikitommi10:05:26

what should the :body be after the stream has been consumed? Empty InputStream?

conan10:05:49

I'm not sure, I didn't realise it would be consumed before reaching a handler function

ikitommi10:05:59

well, the other one if from ring itself, so ring doesn’t seem to be compatible with the ring-spec?

conan10:05:21

if the value is nil, then the key can be removed from the request map to keep it spec-compliant

ikitommi10:05:31

if the body is parsed, the stream is read. Now muuntaja put’s nil in there, could keep the empty stream

ikitommi10:05:39

oh, true that.

conan10:05:43

ok i'll raise an issue with ring middleware and muuntaja

ikitommi10:05:49

I’ll ask James in the #ring channel

ikitommi10:05:26

actually, if you could ask in #ring or via issues. I can fix muuntaja, but need to know how.

conan10:05:26

it's the :query-string

ikitommi10:05:50

oh, what adapter are you using?

conan10:05:10

i'm using httpkit, is that what you mean?

ikitommi10:05:05

it might set the :query-string to nil if it’s not set. If you print out the request coming from the adapter and see if it’s nil.

conan10:05:06

sorry, by adapter do you mean the web server?

conan10:05:27

i'm not familiar with the terminology

ikitommi10:05:28

I would allow nil as it’s more idiomatic Clojure. easy to pipe logic for “there is no query-string set”.

ikitommi10:05:36

yes, I mean

conan10:05:46

let me try, hang on

ikitommi10:05:49

http-kit is both, a web-server and a ring-adapter.

ikitommi10:05:01

jetty is a web-server and there is ring-jetty, which is ring-adapter

conan10:05:40

ok yes, those keys appear to be there before hitting reitit

conan10:05:49

sorry, i must have done something wrong before

conan10:05:02

thanks for your help again!

ikitommi11:05:53

Immutant also doesn’t set the :query-string:

ikitommi11:05:22

{:body #object[io.undertow.io.UndertowInputStream 0x44f9e7f5 "io.undertow.io.UndertowInputStream@44f9e7f5"],
 :character-encoding "ISO-8859-1", :content-length -1, :content-type nil, :context "", :handler-type :undertow,
 :headers {"accept" "image/webp,image/apng,image/*,*/*;q=0.8", "accept-encoding" "gzip, deflate, br",
           "accept-language" "en-US,en;q=0.9,fi-FI;q=0.8,fi;q=0.7", "connection" "keep-alive", "dnt" "1",
           "host" "localhost:9999", "referer" "",
           "user-agent" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"},
 :path-info "/favicon.ico", :query-string nil, :remote-addr "127.0.0.1", :request-method :get, :scheme :http,
 :server-exchange #object[io.undertow.server.HttpServerExchange 0x4a3e10c2 "HttpServerExchange{ GET /favicon.ico request {Connection=[keep-alive], Accept=[image/webp,image/apng,image/*,*/*;q=0.8], Accept-Language=[en-US,en;q=0.9,fi-FI;q=0.8,fi;q=0.7], Accept-Encoding=[gzip, deflate, br], DNT=[1], User-Agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36], Referer=[], Host=[localhost:9999]} response {Server=[undertow]}}"],
 :server-name "localhost", :server-port 9999, :ssl-client-cert nil, :uri "/favicon.ico", :muuntaja/request nil,
 :muuntaja/response #FormatAndCharset{:charset "utf-8",
                                      :format "application/json"}}

conan11:05:45

btw now i've got my head round it, reitit seems sooo much easier than compojure or bidi, i can't wait to ditch my secretary and share the routes as well

👍 8