Fork me on GitHub
#ring-swagger
<
2017-05-25
>
ikitommi06:05:42

Ideas about the new validation errors, comments welcome: https://github.com/metosin/compojure-api/issues/304

kasuko14:05:42

Hey, I am trying to do something a little unorthodox and I was wondering what is responsible for turning the :params key in a request into the lovely :query-params key in the request?

kasuko14:05:47

I thought it might be compojure.api.middleware/api-middleware but I couldn’t figure out how it gets the swagger information

kasuko14:05:30

Context: I am converting our API to use the compojure.api resource style stuff. However we also have websocket subscriptions that work the same way. So I have the :handler function as a defn and I would like to use that same function to handle the WS request too. However that handler is expecting the parameters in :query-params but the WS is passing the params as :params to mimic Ring.

ikitommi17:05:20

@kasuko it’s it other way around, api-middleware installs ring.middleware.params/wrap-params which reads :query-params (and others) into :params. You could write a custom middleware to do this the other way around. With the latest alpha, you can also add middleware directly to resources.

ikitommi17:05:32

the swagger information is collected by the api function (https://github.com/metosin/compojure-api/blob/master/src/compojure/api/api.clj#L18-L73): it reads the paths and transforms their information into swagger definitions, and merges the top-level swagger data to it. Data is injected into the request (together with the reverse-routing information to enable bi-directional routing) and by so, is available to all routes under the api. the swagger-docs handler just reads it from the request.

ikitommi17:05:00

all Routes self-contain all the ring-swagger-data, you can print any Route (`api`, context, GET, resource, …) in the repl to see how their data, including the swagger-stuff.

ikitommi17:05:04

hope this helps.

ikitommi17:05:01

and calling compojure.api.routes/get-routes on a Route gives the cumulative routing tree, with all the extra data.

plins19:05:30

@ikitommi , im taking a look into your example of a spec error what does the :spec "(clojure.spec.alpha/keys :req-un [::a])stands for? this is the error msg that will be sent to the client if it fails to meet the spec?

kasuko20:05:17

@ikitommi thanks! Looks like my task isn’t going to be as easy as I had hoped!

ikitommi20:05:03

@plins that would be the s/form of the spec. The ::a shouldbe :user/a as its expanded there

ikitommi20:05:23

could be under :form...

plins20:05:57

it would be really nice to set a custom msg if some validation fails, sometimes the errors get quite confusing (specially to a third party client consuming the api with no knowledge of clojure at all)

ikitommi20:05:39

custom message per schema/spec or per field?

plins20:05:25

per field would be perfect, but is it possible? maybe i want the impossible here 😛

ikitommi20:05:52

added already a :reason field to spec-tools Spec records, allows per "field"

plins20:05:59

thanks 🙂

plins20:05:17

changing subject here, is there a canonical way of setting a default value for a field? im struggling with limit and offset values

ikitommi20:05:24

Schema doen't have that, but could/should

plins20:05:12

ive read some discussions on github regarding this topic but wasnt able to figure out how to do it

ikitommi20:05:33

default for docs or Real default?

plins20:05:12

real default, in eg. if the user do not provid an offset and limit i could just accept the request (instead of 400) and use some default value

plins20:05:38

its doable by parsing the request by hand but id like to avoid that

ikitommi20:05:52

letk-syntax has that, but if you define schemas as data/maps (e.g. :body or with resources), there isn't a mechanism for that in Schema core.

ikitommi20:05:19

but, there is one in schema-tools (and will be in spec-tools).

ikitommi20:05:27

but to get the defaults in, you need to run explicitely confom or coerce with a conformer/coercer that applies the defaults. And the original spec/schema needs to have a :default data Needs some plumbing to get working now.

ikitommi20:05:29

Today, I would just merge in the defaults. Far from good, but works.

ikitommi21:05:03

@kasuko, maybe do (update request :query-params merge (:params request)) before the handler in the ws?

ikitommi21:05:43

@plins could you write a issue to schema-tools to support per schema valisation error :reason? Now only in spec-side. Would work the same way with both libs.

plins21:05:10

sure! thanks for the insightful info 🙂