如何使用httparty切换base_uri

19

我正在尝试将参数传递给一个login方法,并希望根据该参数切换基础URI。

像这样:

class Managementdb
  include HTTParty

  def self.login(game_name)
        case game_name
        when "game1"
            self.base_uri = "http://game1"
        when "game2"
            self.base_uri = "http://game2"
        when "game3"
            self.base_uri = "http://game3"
        end

    response = self.get("/login")

        if response.success?
      @authToken = response["authToken"]
    else
      # this just raises the net/http response that was raised
      raise response.response    
    end
  end

  ...

当我从一个方法中调用时,基本URI未设置,如何使其工作?

3个回答

19

在 HTTParty 中,base_uri 是一个类方法,它设置了一个内部选项哈希。要从你的自定义类方法 login 中动态更改它,你可以将其作为方法调用(而不是像变量一样分配它)。

例如,根据上面的代码更改,这应该会按你的期望设置 base_uri

...
case game_name
  when "game1"
    # call it as a method
    self.base_uri "http://game1"
...

希望能对你有所帮助。


如果需要在initialize()方法中调用Mixin的类方法,则需要调用YourClassName.mixin_class_method - spier
24
在我的 initialize 方法中,我必须调用 self.class.base_uri "http://example.com" 才能使它工作。 - hamstar
2
@hamstar 但这会改变所有实例的 base_uri 吗?所以,所有实例都会像最后一个一样行为,对吗? - MhdSyrwan
1
请记得在方法调用结束时将 base_uri 更改回原始值,以便您可以再次使用具有原始值的实例。 - Simon L. Brazell

10

我还不能发表评论,因此这里是Estanislau Trepat回答的补充。

要为所有调用设置base_uri,请调用相应的类方法:

self.base_uri "http://api.yourdomain.com"

如果你想要一种仅将少量呼叫发送到不同的URI并避免状态错误(忘记切换回原始URI),则可以使用以下辅助函数:

若您希望只发送少数通话至其他URI,同时避免状态错误(例如忘记返回原始URI),您可以使用以下帮助程序:

(Two possible translations, please choose the one that suits your needs better.)
def self.for_uri(uri)
  current_uri = self.base_uri
  self.base_uri uri
  yield
  self.base_uri current_uri
end
使用上述帮助程序,您可以进行特定的调用以获取其他URI,例如以下内容:
for_uri('https://api.anotheruri.com') do
  # your httparty calls to another URI
end

1
我非常喜欢这种方法。然而,重要的是要注意,这将返回base_uri作为其返回值。如果您需要对返回值执行某些操作,则无法帮助您。为了改进这一点,可以使用response = yield,然后将response作为最后一行以从httparty调用中返回响应值。 - jsookiki
1
我也喜欢这种方法,并使用它...然后意识到了另一件事。如果你的 yield 导致异常,那么你的 base_uri 将会被“卡住”,本应是临时的 base_uri!因此,使用 begin/rescue/ensure 块来确保即使出现异常情况,你的 self.base_uri 也能得到恢复是个好主意。 - nicedawg

8
我不确定在这个问题最初被提出时是否已经实现了,但如果您想在每个请求或每个实例上设置或覆盖:base_uri,HTTParty请求方法(:get、:post等)接受选项来覆盖类选项。

因此对于OP的示例,它可能如下所示:

class Managementdb
  include HTTParty

  # If you wanted a default, class-level base_uri, set it here:
  base_uri "http://games"

  def self.login(game_name)
    base_uri =
      case game_name
      when "game1" then "http://game1"
      when "game2" then "http://game2"
      when "game3" then "http://game3"
      end

    # To override base_uri for an individual request, pass
    # it as an option:
    response = get "/login", base_uri: base_uri

    # ...
  end
end

调用类方法动态地,正如其他答案所建议的那样,会改变所有请求的base_uri,这可能不是你想要的。它肯定不是线程安全的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接