rest-clientでAPIクライアントを書くって記事を書いたんですが、プロキシサーバーの設定によっては正しく接続できないケースがあったのでクライアント自体をFaradayで書き換えることをやりました。

接続できないケースというのは、プロキシサーバーのパスワードに特殊な文字(僕の場合は^+$など)が入っている場合で、エラー内容は残してないですが文字列処理か何かでエラーとなった記憶があります。特殊文字がエスケープできないか、とか色々試したんですが、確かダメだった気が、、ちょっと曖昧です。

rest-client版

以下、rest-clientについて書いたときの記事から転載。

rest-clientで簡易にAPIクライアントを書く - PIYO - Tech & Life -
オープンではないサービスのAPIを使うとき、APIクライアントが無いってことが多いです。なのでアプリケーションから使いたいAPIだけを叩くよ
class ApiClient
  ENDPOINT = 'https://api.example.com/items.json'.freeze

  class << self
    def items(search)
      url = ENDPOINT
      params = {s: search}
      get(url, params)
      return [] if data.nil?

      data['items'].map do |item|
        ItemResponse.new(item)
      end
    end

    def item
      # ...
    end

    private

    def get(url, params)
      res = RestClient.get(url, params: params)
      return nil if res.code != 200

      JSON.parse(res.body)
    end
  end
end

# こんな感じで使う
ApiClient.items('けんさく') => [...]

Faraday版

class ApiClient
  # ENDPOINTはホストまでになる
  ENDPOINT = 'https://api.example.com/'.freeze

  class << self
    def items(search)
      params = {s: search}

      # ENDPOINTは固定なのでpath渡し変えておく
      get('items.json', params)

      # 以下同じ
      return [] if data.nil?

      data['items'].map do |item|
        ItemResponse.new(item)
      end
    end

    private

    def get(path, params)
      conn = Faraday.new(ENDPOINT,
                     proxy: {
                       uri: 'proxy_url'
                       user: 'proxy_account',
                       password: 'proxy_password^+$'
                     })
      res = conn.get(path, params)
      return nil if res.status != 200
      JSON.parse(res.body)
    end
  end
end

# 使い方は一緒
ApiClient.items('けんさく') => [...]

Faraday版の場合はプロキシのアカウントを個別に指定できるので特殊文字が含まれていても問題がありませんでした。