Fork me on GitHub
#ring-swagger
<
2018-08-15
>
rbarker04:08:55

I’m getting errors using compojure-api and therefore ring-swagger with spec coercion enabled - the exception says that there is no spec defined for a keyword ‘Unable to resolve spec’ - however I am simply checking for the presence of a keyword in the response map. Any ideas?

ikitommi06:08:00

@stathissideris we have multiple projects on reitit (and c-api), but nothing big in prod yet - the oldest projects have started last year, haven’t had any rough corners in a while. The routing core is quite stable and proven, ring-side has still some moving parts, and it’s not on par with c-api on all the features. I would say it’s alpha, but so is everything nowadays 😉

ikitommi06:08:56

@rbarker could you show some minimalistic code?

rbarker06:08:53

(GET "foo" []
        :produces ["application/json"]
        :summary "foobar"
        :return (s/get-spec ::foo)
(s/def ::foo (s/keys [::bar]))

rbarker06:08:11

This would cause an exception saying that spec ‘bar’ cannot be found

ikitommi06:08:34

does :return ::foo work?

rbarker06:08:52

I get the error when I try to load the swagger docs

ikitommi06:08:03

is the ::bar defined?

rbarker06:08:38

only by creating a spec (s/def ::bar some?) do the swagger docs load

rbarker06:08:04

my understanding is that if a spec is not defined then simply the presence of the key/value is asserted

ikitommi06:08:23

ok, I thought it would fail too.

ikitommi06:08:40

That should be changed so that if the key is not defined, return nil and handle that gracefully.

ikitommi06:08:00

PR for that welcome.

Empperi10:08:17

I think I found a bug in spec-tools or in compojure-api using it... Not sure though what is causing it currently

Empperi10:08:24

It's a weird one. Everything was working fine until I added nil as a possible value to one of the spec definitions via (s/or ....). After that I get:

my-appl.api/fn             api.clj:   94
                               compojure.api.coercion/coerce-request!        coercion.clj:   45
              compojure.api.coercion.spec.SpecCoercion/coerce-request            spec.clj:  125
                                            clojure.spec.alpha/unform           alpha.clj:  157
                                         spec-tools.core.Spec/unform*           core.cljc:  233
                                            clojure.spec.alpha/unform           alpha.clj:  157
                     clojure.spec.alpha/regex-spec-impl/reify/unform*           alpha.clj: 1658
                                         clojure.spec.alpha/op-unform           alpha.clj: 1449
                                                                  ...                          
                                                  clojure.core/mapcat            core.clj: 2775 (repeats 2 times)
                                                   clojure.core/apply            core.clj:  652
                                                     clojure.core/seq            core.clj:  137
                                                                  ...                          
                                                  clojure.core/map/fn            core.clj: 2745
                                      clojure.spec.alpha/op-unform/fn           alpha.clj: 1449
                                         clojure.spec.alpha/op-unform           alpha.clj: 1446
                                            clojure.spec.alpha/unform           alpha.clj:  157
                       clojure.spec.alpha/map-spec-impl/reify/unform*           alpha.clj:  808
                                            clojure.spec.alpha/unform           alpha.clj:  157
                                         spec-tools.core.Spec/unform*           core.cljc:  233
                                            clojure.spec.alpha/unform           alpha.clj:  157
                          clojure.spec.alpha/every-impl/reify/unform*           alpha.clj: 1274
                          clojure.spec.alpha/tuple-impl/reify/unform*           alpha.clj:  976
                                            clojure.spec.alpha/unform           alpha.clj:  157
                                         spec-tools.core.Spec/unform*           core.cljc:  233
                                            clojure.spec.alpha/unform           alpha.clj:  157
                        clojure.spec.alpha/or-spec-impl/reify/unform*           alpha.clj: 1046
                                                                  ...                          
java.lang.UnsupportedOperationException: nth not supported on this type: Keyword

Empperi10:08:55

This happens when a request comes in and compojure-api tries to coerce the data

Empperi10:08:04

if I remove the compojure-api form the picture and try to validate the input data against the same schema definitions via (s/explain ...) it doesn't break like that but it does report bunch of problems which are due to the fact that coercions have not been ran

ikitommi10:08:54

could you try using spec-tools.core/decode?

Empperi10:08:02

good idea, one moment

Empperi10:08:08

returns :clojure.spec.alpha/invalid but doesn't explode like that

ikitommi10:08:25

btw, go vote up https://dev.clojure.org/jira/browse/CLJ-2251 to get the native coercion into clojure.spec. there is also CLJ-2116 but “not likely to be accepted”

Empperi10:08:44

yeah, would be nice

Empperi10:08:28

calling conform doesn't break it either, let me replicate that logic and see if I get to duplicate the problem

ikitommi10:08:30

the s/invalid? doesn’t work for some reason? shoudn’t be…

mgrbyte10:08:46

think you need to add s/nilable around your spec

👍 4
ikitommi10:08:04

if you copy-paste the code i highlighted and run it locally with the data, does it blow up?

ikitommi10:08:03

and yes, s/nilable is the way to go, but still shoudn’t blow up on error.

Empperi10:08:20

weirdly no, it does not blow up

Empperi10:08:07

but I do not pass transformer in my code snippet

Empperi10:08:34

copy-pasting that stuff would require copying a lot of other stuff also

Empperi10:08:06

but let me try if s/nilable would allow me to go past this problem at this point, that being said this bug should be duplicated with a minimal reproduction case

Empperi10:08:28

this is way too complex as it is now to work as an example case plus I cannot put this anywhere publicly

Empperi10:08:39

right, changing from s/or to s/nilable bypassed the problem

Empperi10:08:13

which is doubly weird

Empperi11:08:40

anyway, I'll try to reproduce this later with a more simple example. Thanks for the ideas which allowed me to bypass this problem this time

Empperi11:08:05

and naturally if I do manage to reproduce it I'll post an issue to github

👍 4
bja13:08:10

is there a good way to turn muuntaja off for a request body?

bja13:08:35

actually, this is the wrong question. I want to add a new format that is simply ignored by muuntaja

ikitommi13:08:41

@bja just for somr routes? Sadly no. The middleware are applied in place, so you would need to disable it at api and re-mount the mw for some routez

bja13:08:28

basically, I want to mount an application/csv that just slurps the request body (or passes it through), but I'd still like muuntaja to handle the response negotiation via Accept

ikitommi13:08:19

It should work out by default?

bja13:08:26

I thought (assoc-in muuntaja/default-options [:formats "application/csv"] {:decoder [slurp]} was close

bja13:08:59

ooh, maybe I did something else that is trying to cause coercion

bja13:08:09

worse, I feel like I figured this out with my old codebase (such that it was documented properly in csv), but I don't have access to said codebase anymore

bja14:08:03

I suppose, alternately, can I add per-endpoint custom swagger documentation?

ikitommi14:08:51

I think the slurp is not right. It should be a function returning the decoder.

ikitommi14:08:14

yep, via :swagger

bja17:08:56

is there a way to encode that the body should be a CSV string in Swagger?

bja17:08:42

looking at the OpenAPI spec, it's not immediately obvious that this is supported for the body, although it seems to be an opt for individual parameters

ikitommi17:08:41

OpenAPI has better options for body, don't think Swagger2 supports those. Setting`:consumes` might help the ui. OpenAPI3-support PRs welcome...

ikitommi17:08:23

Spec-tools is quite close, schema-tools would require some refactoring.