Fork me on GitHub
#reitit
<
2018-09-22
>
valerauko11:09:07

not sure if i've asked this before... how to do query-params properly? currently, while path and body params are key-indexed, query params are string indexed. also, they don't seem to get type-cast: i have a param specced as pos-int? but it still comes through as a string am i missing some setting or something somewhere?

valerauko12:09:16

should've searched before asking. solved!

valerauko12:09:51

actually my problem still stands: i'm coercing my query params like

(s/def ::page pos-int?)
;; ...
{:query (s/keys :opt-un [::page])}
this fails every request with the page set to anything because it's passed as a string, not as a number. how can this be resolved?

ikitommi12:09:05

@vale all coercible specs need to be wrapped, the two ways to do it: 1) use data-spec syntax: {:query {:page pos-int?}}, it just works 2) wrap it manually:

(s/def ::page (spec-tools.core/spec pos-int?))

;; or

(s/def ::page spec-tools.spec/pos-int?)

valerauko12:09:44

can that handle optional parameters?

ikitommi12:09:46

{:query {(ds/opt :page} pos-int?}}

ikitommi12:09:16

(I think we could merge the spec-tools & spec-coerce approaches and make all the simple specs to coerce without any wrapping too)

ikitommi12:09:41

with that, your initial code would work too.

valerauko12:09:27

i figure that'd take changes to reitit itself?

valerauko12:09:14

In: [:parameters :query #spec_tools.data_spec.OptionalKey{:k :page} 0] val: #spec_tools.data_spec.OptionalKey{:k :page} fails spec: :reitit.core.coercion/kw-map at: [:parameters :query :map 0] predicate: keyword?
i tried the ds/opt way but it seems to fail its own spec? am i missing something?

valerauko12:09:39

oh it had to wrapped in a ds/spec

ikitommi13:09:02

did you get it working?

👍 4
valerauko13:09:15

yeah like

{:get {:summary "List of accounts following the user"
             :responses {200 {:body any?}}
             :parameters {:query (ds/spec ::opt-page {(ds/opt :page) pos-int?})}
             :handler user/followers}}]]]

ikitommi13:09:33

it should work without the ds/spec

valerauko13:09:09

without the ds/spec it threw the error i pasted above

4
valerauko13:09:23

i tried {:query {(ds/opt :page) pos-int?}} and it errored

ikitommi13:09:41

that's weird. Could you file an issue out of that?

valerauko13:09:20

there is one already

valerauko13:09:28

at least i think it's the same issue

valerauko16:09:16

is there an api to access the compiled, flattened (final) routes?

valerauko16:09:58

is .compiled-routes something i can rely on? does it change at runtime?

valerauko17:09:10

i'm trying to write a quick macro to generate a bunch of path helper functions

valerauko17:09:17

name lookups make it really easy

ikitommi17:09:19

routers are effectively immutable once created. compiled-routes can be used for extensions, for example the swagger docs are created from those. We'll mark on changelog if the interals change for some reason.

ikitommi17:09:05

what kind of path helpers are you creating btw?

valerauko17:09:26

something like what rails does

valerauko17:09:06

(user-show-path :id 1 :query {:foo "bar"})

ikitommi17:09:39

cool. the ds/spec, worked here ok, commented on the issue...

valerauko17:09:06

is there a way to coerce params in match-by-name! ?

valerauko17:09:12

i have a route with a required param :id pos-int? but it accepts false for example

valerauko17:09:14

(reitit.core/match-by-name! router :person {:id false})

valerauko17:09:26

this makes a Match that has :path-params {:id "false"}, :path "/person-path/false"

ikitommi17:09:20

currently, there is no validation, but one could do that using the route data and reitit.coercion. maybe there should be a helper for it?

valerauko17:09:26

lemme try that

ikitommi17:09:36

currently it would fail when doing the actual route call, not when constructing the path.

ikitommi17:09:50

need to go.

👍 4