jnunemaker/httparty

How can I set base_uri per instance?

Closed this issue · 2 comments

I don't understand why httparty choose to extend, rather than include.

The result is that, how can I set base_uri for each instance of HTTParty.

Say I have a bunch of workers who performs different http requests to different server.
Then they cannot be of the same type, that is I cannot do the following

class Worker
  include HTTParty
  def initialize(host) 
    self.class.base_uri host
  end
end

because the base_uri is a class variable, not an instance variable.

Is there a better way to resolve this? (Maybe by singleton class, I don't know, ruby newbie here)
Or the design here is on purpose for some reason?

I didn't want httparty to mess with the instance. The goal is to have helpers and then do the real work with the instance. If you don't want every thing to use the same base host, don't use that helper. Just pass the host to self.class.get(host) or whatever.

Also, for the future, this is a question that is better served by the mailing list than issues. Issues are for verified bugs, not questions. Just an FYI.

I've written a rubocop cop that can detect incorrect usage of self.class.base_uri:

require 'rubocop'

module RuboCop
  module Cop
    module CustomCops
      # Prevents calling self.class.base_uri (HTTParty)
      # This is because it's a class method meaning it will set the same base URI across all instances of the class
      #
      # # @example
      # # bad
      # class Client
      #   include HTTParty
      #   def initialize
      #     self.class.base_uri "dynamically generated base URI"
      #   end
      # end

      # # good
      # class Client
      #   include HTTParty
      #   base_uri "statically defined base URI"
      # end

      # # good
      # class Client
      #   include HTTParty
      #   def initialize
      #     @base_uri = "dynamically generated base URI"
      #   end
      # end
      class SelfClassBaseUri < Cop
        ERROR = "Don't use self.class.base_uri. Either statically set the base URI, or use an instance variable.".freeze
        def_node_matcher :base_uri?, <<-PATTERN
          (send (send (self) :class) :base_uri (...))
        PATTERN

        def on_send(node)
          return unless base_uri?(node)

          add_offense(node, message: ERROR)
        end
      end
    end
  end
end