passing array of url params in faraday

8.6k views Asked by At

I'm new to Faraday and trying to learn how to pass an array for url params. My code looks like this:

require 'faraday'

conn = Faraday.new(:url => 'http://foo.com:8888') do |faraday|
  faraday.request :url_encoded
  faraday.response :logger
  faraday.adapter Faraday.default_adapter
end

response = conn.get '/api/endpoint', { :bar => ['baz', 'qux'] }
response.body    

When I debug, I see that the URL is getting encoded as:

INFO -- : get http://foo.com:8888/api/endpoint?bar[]=baz&bar[]=qux

instead of http://foo.com:8888/api/endpoint?bar=baz&bar=qux. How do I get faraday to encode the URL without the [] when I'm passing an array of params?

2

There are 2 answers

2
Peter Souter On BEST ANSWER

I see why this is happening now.

This issue is actually fixed on Faraday ver 0.9+, but that's only avaliable as an RC.

So two choices: Change your code to look like this (monkey patch, taken from Ruby's Faraday - include the same param multiple times)

require 'faraday'

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

conn = Faraday.new(:url => 'http://foo.com:8888') do |faraday|
  faraday.request :url_encoded
  faraday.response :logger
  faraday.adapter Faraday.default_adapter
end

response = conn.get '/api/endpoint', { :bar => ['baz', 'qux'] }
response.body 

Or use the pre-release 0.9 version of faraday

gem install faraday --pre

and add this to your code:

faraday.params_encoder = Faraday::FlatParamsEncoder

Which will stop it from adding the [] symbols.

0
harrisjb On

I can't comment so I'll say this: The above answer worked for me, and I have upvoted it, but here's my specific example (I had to move the call to FlatParamsEncoder, I had it in the wrong method initially:

#Gemfile
gem 'faraday', '~> 0.9.0.rc5'

#lib/api_wrapper/faraday_adapter.rb
def patch
  connection.patch do |req|
    req.options.params_encoder = Faraday::FlatParamsEncoder
    req.headers['Content-Type'] = 'application/json'
    req.url "/api/v1/#{end_point}", @request.params
  end
end

def connection
  faraday_client = Faraday.new(:url => base_url) do |faraday|
    faraday.response :logger if Rails.env.development?
    faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
  end
  faraday_client.basic_auth(username, password)
  faraday_client
end