Pass multiple query parameter values with clj-http - clojure

I need to make a web request to an external service (Twilio), with multiple values specified for the same parameter, e.g.
GET /some-url?status=1&status=2&status=3
How do I tell clj-http to encode the request like this?

You can put multiple values for your :query-param value inside of sequential:
(client/get
"http://yoursite.com/some-url"
{:query-params {"status" [1 2 3]}
:debug true})

Related

Generate a response without stripping off default values in protobuf

We have a API where we send the response by parsing it with protobuf contracts and we send the result to the consumers. It strips of some of the fields which has default values(0 for integer, false for boolean etc.) but we don't want to allow that behaviour.
Is there a way that we can either stop protobuf from stripping the default values in response or maybe construct a response with all the default values and merge it with our regular response so that we can send back those fields with default values?
For example, if we have
{"foo": 0.0, "bar": false, "baz": "abc"}
in the response we only get
{"baz": "abc"}
because protobuf strips off the values. But, we also want to get full response with zero values.
We are using below clojure snippet to generate the JSON:
(-> (JsonFormat/printer)
(.print proto)
(json/parse-string true))
(-> (JsonFormat/printer)
(.includingDefaultValueFields)
(.print proto)
(json/parse-string true))
calling (.includingDefaultValueFields) does the trick.

Ruby convert Url parameters to array

I have this url encoded:
Started PUT "/path/thing/9812/close?status=close&shutdown_on=2018-12-05%2010%3A08%3A06&affected_external_id=15027&fqdns%5B0%5D=150.212.3.249"
which decoded is this:
"/path/thing/9812/close?status=close&shutdown_on=2018-12-05 10:08:06&affected_external_id=15027&fqdns[0]=150.212.3.249"
I get this parameters:
Parameters: {"status"=>"close", "shutdown_on"=>"2018-12-05 10:08:06", "affected_external_id"=>"15027", "fqdns"=>{"0"=>"150.212.3.249"}, "id"=>"9812"}
How can get fqdn as a array? on Rails 4
You should do the following:
params[:fqdns].to_a
Doing this, will produce the following:
{['0', '150.212.3.249', ...]}
If you wnat only the values, may you can try:
params[:fqdns].values
Doing this, will give you the following:
['150.212.3.249', ...]
But for this, you have to do it inside a ruby class, i strongly recommends you to do it inside your controller. Hope i can help.
UPDATE
After a recommends, you can do it with strong parameters, permiting the param fqdns as a hash (because you route receiving a hash):
def resource_params
params.permit(....., fqdns: {})
end
After this, you already have to execute the solutions above to get fqsnd as a array

QueryDict getlist returns empty list

I'm sending from frontend object with one property which equal to array.
In backend I need to get data from that array.
when i write request.POST i see:
<QueryDict: {u'response[0][doc_id]': [u'14'], u'response[1][uuid]': [u'157fa2ae-802f-f851-94ba-353f746c9e0a'], u'response[1][doc_id]': [u'23'], u'response[1][data][read][user_ids][]': [u'9'], u'response[0][uuid]': [u'8a0b8806-4d51-2344-d236-bc50fb923f27'], u'response[0][data][read][user_ids][]': [u'9']}>
But when i write request.POST.getlist('response') or request.POST.getlist('response[]') i get
[]
request.POST.get('response') doesn't work as well (returns None).
What is wrong?
Because you don't have either response[] or response as keys, you have the literal strings response[0][doc_id] and response[1][uuid] etc.
If you want to use a structure like this, you should send JSON rather than form-encoded data and access json.loads(request.body).

How do I use Ring to output my post data in a request?

In using clojure-ring I'm trying to do a simple test by posting data form a form and then printing it to the browser.
(defroutes approutes
;posting test
(POST "/upload" [req]
(str "the wonderful world of wonka presents " req)))
when I try posting data via curl it gives me a 200 okay status code, but it doesn't actually fill in the body of the request with the params. Perhaps I am overlooking something fundamental about Ring.
edt:
what it does output is
the wonderful world of wonka presents
but the rest doesn't show up.
compojure's destructuring tries to access the query/form parameter :req in your example, not the whole request. You have two possibilities:
(POST "..." req ...)
and
(POST "..." [something :as req] ...)
Both store the request in req, the second variant allows you to still use destructuring , though.

How to apply a ring-middleware to specific group of routes?

I have a ring middleware which does some check on request maps with the header values.
For the check I have to hit the database.
If a defroutes as a set of routes starting with acommon URI pattern.
I don't want a middleware to run for any random URL that matches the pattern before getting handled.
I only want middleware to run for a certain set of URIs that I am suing inside of defroutes only. The reason being there is a database access in the middleware which I want to avoid for 404 responses having the same pattern.
Here is comporoute, a ring handler without any macro magic, aimed at composability and extensibility.
Even though it's in early alpha state it has precise docstrings already. It has a feature called inner middleware to solve the issue you are having. You may (and should) use it only for what you need it for and leave the rest to Compojure.
Given your Compojure handler/app is called compojure:
(defn demo-middleware
"A test midleware associng :bar to :foo of request"
[handler]
(fn [request]
(handler (assoc request :foo :bar))))
(defn demo-handler [request]
(ring.util.response/response
(str "id is " (get-in request [:params :id]) " "
":foo is" (:foo request))))
(def app
(comporoute.core/router
[["/demo-with-middleware"
[demo-middleware ;; all handlers in this vector are
;; wrapped via demo-middleware
["/:id" :demo-with demo-handler]]]
["/demo-without-middleware"
["/:id" :demo-without demo-handler]]]
:page-not-found compojure)
At the shell
curl http://localhost:8080/demo-without-middleware/1234
id is 1234 :foo is
curl http://localhost:8080/demo-with-middleware/1234
id is 1234 :foo is :bar
# Everything else will be handled by compojure.
Dependency vector [comporoute "0.2.0"]