Ruby's Faraday - include the same param multiple times

不想你离开。 提交于 2020-01-02 05:06:23

问题


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.


回答1:


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



回答2:


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



回答3:


I think the way you call Faraday is not correct. You need to define a connection first (without parameters), and then you call the HTTP method on that connection.

Something like this:

require 'faraday'

client = Faraday::Connection.new :url => "http://api.twitter.com" do |builder|
    builder.response :logger
    # some middleware that helps to process a request/response comes here
end

client.get "search", { a: 1, b:2 }

This should build you this request:

I, [2013-02-05T15:15:40.665955 #57012]  INFO -- : get http://api.twitter.com/search?a=1&b=2


来源:https://stackoverflow.com/questions/14551057/rubys-faraday-include-the-same-param-multiple-times

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!