ring-swagger

ring-swagger & compojure-api
ikitommi 2018-05-01T13:17:15.000245Z

(ns user)

(require '[compojure.api.sweet :refer :all])
(require '[ring.util.http-response :refer :all])
(require '[clojure.spec.alpha :as s])
(require '[spec-tools.spec :as sts])

(s/def :species/id sts/keyword?)

(def app
  (api
    {:coercion :spec}
    (POST "/body" []
      :body-params [species/id :- :species/id]
      :return :species/id
      (prn id)
      (ok id))))

(->
  {:request-method :post
   :uri "/body"
   :body-params {:species/id "species/c-elegans"}
   :headers {"content-type" "application/json"}}
  (app)
  :body
  slurp)
; :species/c-elegans
; => "\"species/c-elegans\""

ikitommi 2018-05-01T13:17:20.000280Z

ping @mgrbyte

ikitommi 2018-05-01T13:17:42.000119Z

It seems to be working correctly?

mgrbyte 2018-05-01T13:21:45.000323Z

It's fine for decoding, not sure how to encode

mgrbyte 2018-05-01T13:22:39.000434Z

i.e given JSON: {"species/id": "species/c-elegans"} want to turn it back into the clojure form {:species/id :species/c-elegans}

ikitommi 2018-05-01T13:23:24.000067Z

ok, just a sec.

mgrbyte 2018-05-01T13:23:53.000361Z

or else am looking for a pattern of how data is sent to the app in e.g a post request

ikitommi 2018-05-01T13:27:09.000027Z

(ns user)

(require '[muuntaja.core :as m])
(require '[compojure.api.sweet :refer :all])
(require '[ring.util.http-response :refer :all])
(require '[clojure.spec.alpha :as s])
(require '[spec-tools.core :as st])
(require '[spec-tools.spec :as sts])

(s/def :species/id sts/keyword?)
(s/def :species/map (s/keys :req [:species/id]))

(def app
  (api
    {:coercion :spec}
    (POST "/body" []
      :body-params [species/id :- keyword?]
      :return :species/map
      (ok {:species/id id}))))

(->
  {:request-method :post
   :uri "/body"
   :body-params {:species/id "species/c-elegans"}
   :headers {"content-type" "application/json"}}
  (app)
  :body
  slurp
  (->> (m/decode (m/create) "application/json"))
  (as-> value
        (st/conform :species/map value st/json-conforming)))
; => #:species{:id :species/c-elegans}

ikitommi 2018-05-01T13:29:39.000063Z

or:

mgrbyte 2018-05-01T13:31:31.000377Z

am just trying out those samples now

mgrbyte 2018-05-01T13:39:16.000191Z

@ikitommi ah, so I was missing the conforming step: (st/conform :species/map value st/json-conforming)))

mgrbyte 2018-05-01T13:39:53.000472Z

also, I've not been using spec-tools for conforming thus far (using clojure.spec directly)

mgrbyte 2018-05-01T13:40:33.000106Z

thank you v. much; so I should probably change all my handlers to manually conform using st/json-conforming thinking_face will think about how to incorporate this.

mgrbyte 2018-05-01T13:51:20.000217Z

@ikitommi Sorry, I'm quite confused now. Running the last sample you posted, I can see it works as I'd expect. My app must be doing something different/have a bug somewhere that I can't see. thanks again for your help, I'll keep looking...

ikitommi 2018-05-01T14:14:23.000078Z

np. hope tou get it working

mgrbyte 2018-05-01T14:20:39.000296Z

@ikitommi found the error. Thought json-conforming was the default (and it is) My mistake was trivial; was using :body instead of :body-params in my resource definition. (I'll admit to be not entirely clear on the diference between using the two)

mgrbyte 2018-05-01T14:22:03.000209Z

/me goes to grep the docs