I'm working against an API that forces me to send the same parameter's name multiple times to cascade different filtering criteria. So a sample api GET call looks like this:
GET http://api.site.com/search?a=b1&a=b2&a=b3&a=c2
I'm using Faraday for my REST adapter, which takes its URL parameters as a Hash (therefore - it has unique keys). This means I cannot do something like this:
response = Faraday.new({
url: 'http://api.site.com/search'
params: { a: 'b1', a: 'b2', a: 'b3', a: 'c2' } # => nay
}).get
I tried to hack on the url right before the request is sent:
connection = Faraday.new(url: 'http://api.site.com/search')
url = connection.url_prefix.to_s
full_url = "#{ url }?a=b1&a=b2&a=b3&a=c2"
response = connection.get( full_url )
Which did not work - when I debug the response I see that the actual url sent to the API server is:
GET http://api.site.com/search?a[]=b1&a[]=b2&a[]=b3&a[]=c2
I have no way to change the API. Is there a way to keep working with Faraday and solve this in an elegant way? thanks.
I've been trying to figure out how to do this for a while now. I ended up digging through the Faraday code, and found exactly this use case in the test suite.
:params => {:color => ['red', 'blue']}
should yield
color=red&color=blue
If you don't want upgrade to 0.9.x
module Faraday
module Utils
def build_nested_query(value, prefix = nil)
case value
when Array
value.map { |v| build_nested_query(v, "#{prefix}") }.join("&")
when Hash
value.map { |k, v|
build_nested_query(v, prefix ? "#{prefix}%5B#{escape(k)}%5D" : escape(k))
}.join("&")
when NilClass
prefix
else
raise ArgumentError, "value must be a Hash" if prefix.nil?
"#{prefix}=#{escape(value)}"
end
end
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With