This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-07-30
Channels
- # babashka (44)
- # beginners (29)
- # calva (80)
- # cider (11)
- # clara (1)
- # clj-kondo (9)
- # clojure (80)
- # clojure-europe (21)
- # clojure-france (13)
- # clojure-nl (4)
- # clojure-spec (3)
- # clojure-uk (6)
- # clojurescript (72)
- # code-reviews (43)
- # cursive (11)
- # datomic (27)
- # events (13)
- # figwheel-main (12)
- # fulcro (27)
- # graalvm (1)
- # jackdaw (2)
- # kaocha (1)
- # malli (4)
- # meander (13)
- # nrepl (2)
- # pathom (8)
- # re-frame (4)
- # reagent (7)
- # reitit (9)
- # remote-jobs (1)
- # reveal (56)
- # ring-swagger (2)
- # sci (5)
- # shadow-cljs (20)
- # slack-help (2)
- # tools-deps (96)
- # vim (7)
- # xtdb (30)
Hi, I’m trying to create a POST route with compojure-api using spec.
My login-params
spec has login
and password
as strings.
This: :body-params [params :- ::login-params]
gives me this as a request body in swagger:
{
"params": {
"login": "string",
"password": "string"
}
}
I’d like to remove that params
key, and make login
and password
the root values of the POST body, but I can’t seem to find the incantation to do it. Am I missing something obvious? I’m using this as an example of more complex specs as POST body later, so I’d prefer not to put the login
and password
directly in the vector. Thanks so much!@hoopes I know nothing about compojure-api but I wonder if you could just say :body-params ::login-params
?
yeah, that was the first thing i tried 🙂 java.lang.UnsupportedOperationException: count not supported on this type: Keyword
I’ve tried a bunch of different permutations, but all result in one error or another except the line above
Sorry... ¯\(ツ)/¯
is there a better channel to ask in? it seems a little beginner-y to open an issue on the repo, unless it might cause a doc update
@hoopes I don't know. There's doesn't seem to be a channel for Compojure API although some of the Metosin projects have their own channels...
They're based in Europe so maybe asking during a time they're online (on a weekday, perhaps)... and maybe tagging one of the main contributors or maintainers?
@hoopes @seancorfield I recall it's: :body [params ::login-params]
, the macro generates a let
statement out of it. And there is #ring-swagger. Compojure-api would desperately need someone to write proper docs.
Hi @U055NJ5CC - i get the error
Caused by: java.lang.IllegalArgumentException: Binding is not valid, please refer to
for more information.
binding: [params :my-ns/login-params]
did you mean: [params :- :my-ns/login-params]
Which, in turn, puts the params
key in my POST body, which i'd like to avoid. I eventually found:
(resource
{:coercion :spec
:post {:parameters {:body-params ::tok-spec/login-params}
:responses {200 {:schema ::tok-spec/token-resp}}
:handler create-token}})))
Which gives me the clean login
and password
as top-level keys in the POST body.But does not auto-coerce the response map to the given spec. I can do that by-hand, though.
there is a nice "full" compojure-api example here to look for tips: https://github.com/yogthos/memory-hole
Hello, is there some reason in my code that these two functions have very different performances (this is in Cljs)?
(def test-file (fs/readFileSync "/tmp/test-file" "utf8"))
(let [start-time (js/Date.now)
x (map js/JSON.parse (string/split-lines test-file))]
(prn (str "Clj - Count: " (count x) ", Time: " (- (js/Date.now) start-time)))) ;; Clj - Count: 985, Time: 10254
(let [start-time (js/Date.now)
x ((js/eval "x => x.split('\n').filter(x => !!x).map(JSON.parse)")
test-file)]
(prn (str "JS - Count: " (count x) ", Time: " (- (js/Date.now) start-time)))) ;; JS - Count: 985, Time: 774
It looks like clojure.string/split
has different performance (https://cljs.github.io/api/clojure.string/split) so I’m just going to call out to JavaScript’s (.split test-file)
instead
Suppose I have a map of functions like {:fn1 my.functions/fn1 :fn2 my.functions/fn2 ...}
. Is there Clojure function that will invoke one of those functions in a thread first context? For example (-> (my-function-map :fn1) <invoke> (assoc :number 42)
<invoke>
would call the function that resulted from the function map and, presumably, returns a map which is then threaded into the assoc.
@mafcocinco I think it would just be easier to wrap extra (..)
around that first expression to invoke it.
(-> ((my-function-map :fn1)) (assoc :number 42)
that will do it. I could also bind it to a name with a let
. Was more curious than anything so figured i would ask. Binding it to a name might actually be the best way from a readability stand-point, but opinions may vary.
But if you really want it in the threaded expression, I think this would do it: (-> (my-function-map :fn1) (#(%)) (assoc :number 42))
-- I just don't think that's very clear.
Or (-> (my-function-map :fn1) (as-> f (assoc (f) :number 42)))
as->
is useful inside a ->
pipeline for naming something and using it in a non-first-argument way.
@mafcocinco (-> {:a (fn [] {:str "string"})} :a (apply nil) (assoc :number 42))
?
Ooh, (apply nil)
that's a nice, sneaky way of doing it!
yeah, trying not be clever. I think it is clearer to either invoke it on the part of the threading macro or, if that is not possible, bind it to a name.