Fork me on GitHub
#ring-swagger
<
2017-07-19
>
ikitommi09:07:08

@serg @plins I’ll take a look at those.

ikitommi09:07:15

btw, it’s awesome that #cursive does static analysis on the c-api routes.

serg09:07:27

@ikitommi I am using "1.1.10"

serg09:07:49

>Is it possible that you are redefining the Tag later in the code`? Nope the code is pretty simple

ikitommi09:07:26

Hmm.. did a new project from the template and run the code with 1.1.10, works as expected. Could you try this:

ikitommi09:07:58

lein new compojure-api c1
, edit handler.clj & lein ring server

ikitommi09:07:08

with this contents:

(ns c1.handler
  (:require [compojure.api.sweet :refer :all]
            [ring.util.http-response :refer :all]
            [schema.core :as s]))

(s/defschema Collection
  {:id s/Int
   :name s/Str})

(s/defschema Tag
  {:id s/Int
   :tag s/Str})

(def app
  (api
    (swagger-routes)
    (context "/:storeId" []
      (GET "/collections" {:as request params :params}
        :summary "Get Collections"
        :path-params [storeId :- s/Str]
        :return [Collection]
        (ok [{:id 101 :name "My Collection"}]))

      (GET "/tags" {:as request params :params}
        :summary "Get Tags"
        :path-params [storeId :- s/Str]
        :return [Tag]
        (ok [{:id 101 :tag "My Collection"}])))))

serg09:07:50

@ikitommi hmm, yes, working for me too

serg09:07:04

thanks, I will analyze more what the diff

ikitommi09:07:51

np, hopefully you get it resolved.

ikitommi09:07:49

@plins looked into the :return thing…. did that work with pre-2.0.0?

ikitommi09:07:09

because :return only sets the response validation for status code 200 (in master at least).

bja14:07:52

@ikitommi can anyone edit the wiki? if not, can you fix a typo/rename in the Coersion docs that explain how to revert to the pre-2.0 coerce+validation of responses. The example shows schema-coercion/json-coercion and at some point, it became schema-coercion/json-coercion-matcher. Full (working) example is something like this:

(def compojure-1x-coercion
  (schema-coercion/create-coercion
   (assoc-in schema-coercion/default-options [:response :default] schema-coercion/json-coercion-matcher)))

ikitommi14:07:37

@bja thanks. anyone can contribute to wiki. Looking forward to awesome enchancements ;)

plins14:07:03

@ikitommi, i did work pre-2.0.0 with 200 responses, not sure about 201 (or other http status) i will examine your snippet and check if adding :responses instead of :return fixes the problem thank you

plins15:07:46

@ikitommi, just updated my code like your snippet, and instead of getting a 500 status code the api is returning 400 and raising this strange exception Exception in thread "async-dispatch-6" clojure.lang.ExceptionInfo: Response validation failed: #compojure.api.coercion.core.CoercionError` here is the http repsonse from the server

{
  "spec": "(spec-tools.core/spec {:spec (clojure.spec.alpha/keys :req-un [:payment-gateway.spec/cpf :payment-gateway.spec/name :payment-gateway.spec/email] :opt-un [:payment-gateway.spec/creditCard]), :type :map, :keys #{:cpf :email :name :creditCard}})",
  "problems": [
    {
      "path": [],
      "pred": "map?",
      "val": null,
      "via": [],
      "in": []
    }
  ],
  "type": "compojure.api.exception/request-validation",
  "coercion": "spec",
  "value": null,
  "in": [
    "request",
    "body-params"
  ]
}

ikitommi16:07:29

@plins looks like you are sending empty body while the endpoint expects something. You have also an input spec defined?

plins17:07:05

this should fail

plins17:07:15

(def routes
  (api/context "/api" []
    :coercion :spec

    (api/POST "/user" []
      :summary "Cadastra Taxistas ou Passageiros"
      :body [request (spec/keys :req-un [::s/cpf ::s/name ::s/email]
                                :opt-un [::s/creditCard])]
      :responses {201 {:schema (spec/keys :req-un [::s/customerId]
                                          :opt-un [::s/creditCardId])}}
      (go (res/created "" request)))))

plins17:07:45

since the input and the output expects different specs, and im returning the route input

plins17:07:10

this is what im sending

plins17:07:36

POST /api/user HTTP/1.1
Host: localhost:3000
Content-Type: application/json
Cache-Control: no-cache
{
  "name" : "Batman dos Santos Oliveira Junior",  
  "email" : "",
  "cpf" : "29774456092",
  "creditCard" :  {
   "holdersName"      : "BATMAN S O JUNIOR", 
   "creditCardNumber" : "1111222233334444",
   "expirationMonth"  : "07",
   "expirationYear"   : "2020",
   "cvc"              : "1323" 
   }
}