Is there a way to use the resource
function with :spec coercion and make a default value for a parameter?
Using the macro syntax I would do {id :- :my/id nil}
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
The difference between these two https://github.com/metosin/compojure-api/blob/master/examples/coercion/src/example/data_spec.clj#L12-L20
It looks like :parameters {:query-params {:x int?, :y int?}}
doesn't make :y
optional, like it did above
Ah, I've found a way, use s/keys
on the parameters with an :opt
:parameters {:query-params ::input-settings}
(s/def ::input-settings (s/and (s/keys :req-un [::endpoint
::requestor-id]
:opt-un [::from-year
::requestor-name])))
@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})
optional key with data-spec syntax: :parameters {:query-params {:x int?, (ds/opt :y) int?}}
Nice! That's very useful. Thanks!
@kjothen not sure what you mean, swagger with compojure-api without the auto-generated route docs?
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?
@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.
@florinbraghis I think you can't have both names & the fnk
syntax. Ideas welcome on this.
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 ?
@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?
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.
Thanks ikitommi, I’ll try to come up with a PR for this, we can take this discussion to github then!
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.
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 ?