ring-swagger & compojure-api
danielcompton 2018-12-05T09:23:04.029400Z

Is there a way to use the resource function with :spec coercion and make a default value for a parameter?

danielcompton 2018-12-05T09:23:33.030100Z

Using the macro syntax I would do {id :- :my/id nil}

danielcompton 2018-12-05T09:25:26.030800Z

but I'm not sure how to do it in the map syntax. I've tried making the spec nilable, but that didn't work

danielcompton 2018-12-05T09:32:36.031300Z

The difference between these two https://github.com/metosin/compojure-api/blob/master/examples/coercion/src/example/data_spec.clj#L12-L20

danielcompton 2018-12-05T09:32:57.031900Z

It looks like :parameters {:query-params {:x int?, :y int?}} doesn't make :y optional, like it did above

danielcompton 2018-12-05T09:40:58.032500Z

Ah, I've found a way, use s/keys on the parameters with an :opt

danielcompton 2018-12-05T09:42:15.032700Z

:parameters {:query-params ::input-settings}

danielcompton 2018-12-05T09:42:38.033Z

(s/def ::input-settings (s/and (s/keys :req-un [::endpoint
                                       :opt-un [::from-year

ikitommi 2018-12-05T09:49:32.035600Z

@danielcompton we just added the working default-value handling to schema-tools, could be added to spec-tools if there would be extra hours in days…. but you can declare the defaults to swagger already, they get injected into the ui: instead of just int? you can say (st/spec {:spec int? :swagger/default 1})

ikitommi 2018-12-05T09:51:24.036400Z

optional key with data-spec syntax: :parameters {:query-params {:x int?, (ds/opt :y) int?}}

danielcompton 2018-12-05T10:02:44.036600Z

Nice! That's very useful. Thanks!

ikitommi 2018-12-05T15:54:55.039900Z

@kjothen not sure what you mean, swagger with compojure-api without the auto-generated route docs?

ikitommi 2018-12-05T15:56:09.041800Z

spec-tools readme has an example how to use that without c-api. You can write the spec manually too, but the end result we be ~the same, right?

kjothen 2018-12-05T16:07:30.050500Z

@ikitommi I posed the question because I’m using clojure.spec to define my message protocol front-to-back, but was struggling to generate swagger from routes using clojure.spec. However, I have it working now, but of course my swagger is now missing some niceties such as object definitions.

ikitommi 2018-12-05T18:41:31.054600Z

@florinbraghis I think you can't have both names & the fnk syntax. Ideas welcome on this.

florinbraghis 2018-12-06T16:43:56.062700Z

A couple of ideas that could help: 1. There could be an optional callback that users can supply in the options, which receives this Swagger map that they can modify freely, called just before ensure-body-and-response-schema-names 2. Instead of BodyXXX and ResponseXXX, adopt a more predictable naming scheme for unnamed schemas. For example, MethodPathBody for body params inline schemas (eg. GetApiPlusBody, GetDocuments{id}Body) and MethodPathResponseCode for responses (eg. GetApiPlusResponse200 GetDocuments{id}Response401). 3. Both or something even better? What do you think about these solutions ?

ikitommi 2018-12-06T18:27:28.062900Z

@florinbraghis I think providing the options is a good idea, also the callback for the schema naming. Are there any other (non-clojure) naming conventions for swagger out there? Would you like to do a PR for spec-tools?

ikitommi 2018-12-06T18:29:21.063100Z

oh, you are using Schema. We started to port Schema->Swagger from ring-swagger to schema-tools. Not on par yet, but at some point will make c-api use that instead.

florinbraghis 2018-12-07T19:06:06.072100Z

Thanks ikitommi, I’ll try to come up with a PR for this, we can take this discussion to github then!

ikitommi 2018-12-05T18:49:27.062300Z

spec-integration is still kinda rough, as both coercion and spec walking are out of clojure.spec and we need to reverse-engineer a lot of things to get it working. Good to hear it works for you! Also looking forward to the spec object definitions.

florinbraghis 2018-12-05T20:00:58.062500Z

Our API has dozens of inline schemas and the only solution that kind of works is to use defschema to create named schemas and use those instead of the inline ones. Needless to say, that’s an almost total rewrite of our API and still there’s the issue of how to name these schemas. To automate this, I’ve ended up using alter-var-root to override ring.swagger.swagger2/ensure-body-and-response-schema-names and generate the schema name from the combination of method-path-body (for body-params) and method-path-response-code for responses. I’m not entirely happy with having to use alter-var-root — maybe there’s another place where I could plug my schema-name-generating function ?