This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-06-22
Channels
- # bangalore-clj (6)
- # beginners (110)
- # boot (49)
- # cider (13)
- # cljs-dev (35)
- # cljsrn (5)
- # clojure (145)
- # clojure-conj (3)
- # clojure-dev (60)
- # clojure-italy (2)
- # clojure-nl (3)
- # clojure-russia (3)
- # clojure-serbia (1)
- # clojure-spec (116)
- # clojure-uk (58)
- # clojurescript (235)
- # cursive (14)
- # datascript (7)
- # datomic (31)
- # dirac (144)
- # emacs (1)
- # events (1)
- # hoplon (12)
- # leiningen (11)
- # luminus (60)
- # lumo (19)
- # off-topic (18)
- # om (74)
- # onyx (5)
- # pedestal (13)
- # precept (3)
- # re-frame (3)
- # reagent (15)
- # remote-jobs (7)
- # ring-swagger (25)
- # rum (1)
- # untangled (53)
- # vim (3)
Hi I'm trying to implement a copy operation for an API. We've decided to implement it as something like POST /myresource?sourceresourceid=x
with no body. I first tried creating a separate (POST) macro and that didn't work in terms of it showing up in the Swagger page as another entry. i've also tried just adding a :query-param to the existing (POST "/myresource"..) but the query param doesn't show up in the existing definition when I do that either. Is this supported?
@eoliphant hi. not sure about the question, but this works:
(def app
(api
{:swagger
{:ui "/"
:spec "/swagger.json"}}
(POST "/my-resource" []
:query-params [sourceresourceid :- s/Str]
(ok {:id sourceresourceid}))))
Hi @ikitommi, indeed it does. I think I'd been working too long without a break and totally missed that it'd showed up lol. My original question was around doing something like the following
(POST "/my-resource" []
:query-params [sourceresourceid :- s/Str]
(ok {:id sourceresourceid}))
(POST "/my-resource" []
:body [something Something]
(ok ))
And getting both POSTs described in the swaggerFor example I have the following:
(POST "/roles" []
:query-params [sourceroleid :- String]
:summary "Copy a role"
(ok))
(POST "/roles" []
:body [role roleEntry]
:summary "Add a new role"
(let [retval (r/add-role role)]
(if (f/failed? retval)
(bad-request {:message (f/message retval)})
(created "/role" role))))
When I do this only the first one wins in terms of what shows up in swagger. I'd hoped to be able to do it that way to simplyfy the API handling
If I do this
(POST "/roles" []
:body [role roleEntry]
:query-params [sourceroleid :- String]
:summary "Add a new role"
(let [retval (r/add-role role)]
(if (f/failed? retval)
(bad-request {:message (f/message retval)})
(created "/role" role))))
I guess I need to make both the body and the parameter optional, and handle the fact that you should have one or the other programmatically?@eoliphant We've used an empty body for PUT before:
(PUT "/" request
:name :update-foo
:summary "Update a foo"
:return {:data {}}
(do ...))
Hmm, but is that going to work in my case. Since if it's truly a new one, then I want a valid JSON, if not then I want nothing (or an empty string, etc) and expect to see the sourceroleid param. Wouldn't the body validation fail in that case?
also, SN, do you know how to specify an optional :query-param? like if I have :query-param [a :- String, b :- String]
but b isn't required. It's pretty straightforward in the (defschemas) but i'm not seeing how to do in in this case
hi all I’m trying to build rest api with compojure-api I have the following definition:
(context "/api" []
:coercion :spec
(POST "/decision" []
:return string?
:body [body string?]
(ok
{:foo body}))
...)
curl -0 -v POST \
-H 'Content-Type: text/json; charset=utf-8' \
-d @- << EOF
"foo"
EOF
{
"spec": "(spec-tools.core/spec {:spec clojure.core/string?, :type :string})",
"problems": [
{
"path": [],
"pred": "clojure.core/string?",
"val": null,
"via": [],
"in": []
}
],
"type": "compojure.api.exception/request-validation",
"coercion": "spec",
"value": null,
"in": [
"request",
"body-params"
]
}
(defn coerce-request! [model in type keywordize? open? request]
(let [transform (if keywordize? walk/keywordize-keys identity)
value (transform (in request))]
(if-let [coercion (-> request
(get-request-coercion)
(resolve-coercion))]
(let [model (if open? (cc/make-open coercion model) model)
format (some-> request :muuntaja/request :format)
result (cc/coerce-request coercion model value type format request)]
(if (instance? CoercionError result)
(throw (ex-info
(str "Request validation failed: " (pr-str result))
(merge
(into {} result)
{:type ::ex/request-validation
:coercion coercion
:value value
:in [:request in]
:request request})))
result))
value)))
how can I make compojure-api to to bind the passed body
to the declared variable in handler?
even sticking to schema it seems my body is nil
(POST "/decision" []
:return s/Str
:body [body s/Str]
(ok
(foo body)))
results in:
{
"schema": "java.lang.String",
"errors": "(not (instance? java.lang.String nil))",
"type": "compojure.api.exception/request-validation",
"coercion": "schema",
"value": null,
"in": [
"request",
"body-params"
]
}