I'm using ring-swagger via compojure-api. I have a few query parameters and I'm struggling to find a way to add a description to a single query parameter. I can add the summary of the entire endpoint but that's not enough.
Is it possible to add a swagger description to a single query parameter using ring-swagger/compojure-api?
compojure.api.sweet/describe.
For example:
(GET "/hello" []
:query-params [name :- (describe String "This is the swagger description for the parameter")]
(ok {:message (str "Hello, " name)}))
Related
I want to create helper function that modifies output returned by higher-order function.
Example of higher-order function:
(def use-meta-sub (make-app-fn (make-sub :meta)))
The problem is that when using this in let like this:
(let [meta-sub (use-meta-sub props :get-me-meta-of-this)])
returns map of key-value pairs like this:
{:key-we-almost-never-need-1 nil
:key-we-almost-never-need-2 nil
:key-we-almost-never-need-3 nil
:key-we-almost-never-need-4 nil
:meta-data {:something-useful "foo"
:more-usefull "bar"
:and-so-on "baz"}}
I would like to target only this :meta-data key
I tried this and some other variations:
(defn use-meta-data-sub [props ctrl]
(:meta-data (use-meta-sub props ctrl))) ;; both with get
It does not work because (I think, that returns lazy sequence and I do not know how to actually firs evaluate it and then extract the key from output).
Is this possible without editing 1st higher-order function, and other two it contains?
(I read all documentation on clojure site and clojure-unraveled, either I do not understand them, or they do not cover this)
I have a following EDN file
:abc #request/builder/abc {
"def" #request/builder/def {
"someVector" ["sample1", "sample2"]
}
}
I have defined custom tag reader in Clojure, which internally calls java code
(defn custom-readers []
{
#request/builder/def defBuilder
#request/builder/abc abcBuilder
}
)
(defn defBuilder [params]
(.defBuilder (someJavaUtilityClass.) params)
)
(defn abcBuilder [params]
(.abcBuilder (someJavaUtilityClass.) params)
)
When I read EDN using edn/read-string, defBuilder executes first and its value gets passed to abcBuilder.
I want to reverse the order of execution without modifying EDN. I want to modify abcBuilder code such that if java call in abcBuilder returns some value then only execute defBuilder. How can I achieve this.
I tried by modifying code as below
(defn defBuilder [params]
'(.defBuilder (someJavaUtilityClass.) params)
)
(defn abcBuilder [params]
if((.abcBuilder (someJavaUtilityClass.) params)
(eval (get params "def"))
)
)
But this throws error like it "Unable to resolve someJavaUtilityClass and params". Is there a better way to solve this?
I'm afraid that's not possible. That isn't how EDN's tagged literals work. The tag handler is called after reading the form, which includes calling the tag handlers for any tagged literals in the form. In other words, the tag handlers are called inside-out.
If this weren't the case, then what a tag means will depend on where that tagged literal is situated, which is needlessly context dependent.
Check out: https://github.com/edn-format/edn#tagged-elements
Here's the relevant part:
Upon encountering a tag, the reader will first read the next element (which may itself be or comprise other tagged elements), then pass the result to the corresponding handler for further interpretation, and the result of the handler will be the data value yielded by the tag + tagged element, i.e. reading a tag and tagged element yields one value.
Also check out: https://clojure.org/reference/reader#tagged_literals
This is about the Clojure reader. And again, here is the relevant bit:
by invoking the Var #'my.project.foo/bar on the vector [1 2 3]. The data reader function is invoked on the form AFTER it has been read as a normal Clojure data structure by the reader.
Also, symbols can only contain one /, delimiting the namespace and the name. Check out: https://github.com/edn-format/edn#symbols
I have JSON data in the following format:
{"load":{"meta": 12345}}
{"load":{"meta": 54321}}
...
When I attempt to load the data with Cheshire I get back only the first line of data translated into edn:
(def read-json-data (parse-string (slurp "data/json_data") true))
=> {:load {:meta 12345}}
If anybody has come accross this and can help show how to read the whole file would be much appreciated.
This is correct behaviour - cheshire/parse-string parses the first JSON object it can find.
If you want the whole file to be parsed as a single JSON object you should make an array:
[{"load": {"meta": 12345}},
{"load": {"meta": 54321}},
...]
Alternatively, if you want to parse each line separately you can do something like this:
(map #(cheshire/parse-string % true)
(line-seq (clojure.java.io/reader "data/json_data")))
(Also, notice the colons in the JSON.)
I have some code need first insert into db and then query back from db. I could either use nested let as below:
(let [sql "sql text"]
(clojure.java.jdbc/insert! ...)
(let [query-result (clojure.java.jdbc/query ...)]
(some-code-using query-result)))
or use one let but use some dummy variable as below:
(let [sql "sql text"
dummy (clojure.java.jdbc/insert! ...)
query-result (clojure.java.jdbc/query ...)]
(some-code-using query-result))
Which one is better and typical usage in clojure?
The canonical name for the "dummy" variable is _, and will make it clear that you don't intend to use the result of that call. Using _ is also easier to follow than nested let calls.
(let [sql "sql text"
_ (clojure.java.jdbc/insert! ...)
query-result (clojure.java.jdbc/query ...)]
(some-code-using-query-request))
There's nothing wrong with nesting let forms, I would say the former of your examples is the most readable thanks to a clearer separation of intent.
I am using ELK (logstash, ES, Kibana) stack for log analysis and Riemann for alerting. I have logs in which users is one of the fields parsed by logstash and I send the events to riemann from riemann output plugin.
Logstash parses logs and user is one of the field. Eg: logs parsed
Timestamp user command-name
2014-06-07... root sh ./scripts/abc.sh
2014-06-08... sid sh ./scripts/xyz.sh
2014-06-08... abc sh ./scripts/xyz.sh
2014-06-09... root sh ./scripts/xyz.sh
Logstash:
riemann {
riemann_event => {
"service" => "logins"
"unique_user" => "%{user}"
}
}
So users values will be like: root, sid, abc, root, sid, def, etc....
So I split stream by user i.e one stream for each unique user. Now, I want to alert when number of unique users count go more than 3. I wrote the following but it's not achieving my purpose.
Riemann:
(streams
(where (service "logins")
(by :unique_user
(moving-time-window 3600
(smap (fn [events]
(let
[users (count events)]
(if (> users 3)
(email "abc#gmail.com")
))))))))
I am new to Riemann and clojure. Any help is appreciated.
email returns a stream. Therefore, for it to work, you must either use it as a stream, by passing it as a parameter to another stream, or use call-rescue to send an event to it directly. Additionally, streams that are meant to receive events from multiple sources (such as your alert destination) should be created once, and stored in a variable for re-use.
First approach, using only abstract streams:
(let [alert (email "abc#gmail.com")]
(streams
(where (service "logins")
(by :unique_user
(moving-time-window 3600
(smap folds/count
(where (> metric 3) alert)))))))
Second approach, using call-rescue:
(let [alert (email "abc#gmail.com")]
(streams
(where (service "logins")
(by :unique_user
(moving-time-window 3600
(fn [events]
(when (> (count events) 3)
(call-rescue (last events) alert))))))))