0

我正在处理一个需要我执行以下操作的 API(无法更改 API):

  1. 登录服务使用它(登录)
  2. 使用 api 方法从登录和一些 api 方法特定参数传递一些令牌信息(每个这样的方法调用都包装在它自己的“api_user”方法中 - 见下文)。

但是,在第 2 步中,api 可能会导致某些异常,在这种情况下,我必须重试登录方法并使用新令牌再次调用相同的 api。每个 api 方法都可能有额外的参数(除了 token 参数)。从概念上讲,如果我已经登录,我现在拥有可以使用一段时间的令牌。

def api_user
  begin
    api_method1 token, x,y,z
  RetryException => e
    new_token = login
    api_method1 token, x,y,z
  end
end

我该如何优雅地做到这一点?选项1:

对于每个 api_user 方法 - 单独执行上述操作

选项 2:使用 ruby​​ 的元编程。我试图在下面展示这一点。

class Y
  def self.api_invoker(token,y,z)
    if token == 'old'
      raise "Old token - renew it"
    end 
    puts "Token = #{token}"
  end 

  def self.call_method(m, *params)
    method = Y.method(m)
    begin
      method.call(*params)
    rescue Exception => e
      if e.message.include? "Old token"
        puts "params before = #{params}"
        params[0] = "new"
        puts "params after = #{params}"
        method.call(*params)
      end 
    end 
  end 

end

如果您按如下方式调用上述方法,则会触发重试并将“新”令牌传递给该方法的第二次调用。

Y.call_method("api_invoker", "old",2,3)

我不喜欢从 1 开始的设计。虽然我更喜欢选项 1,但它似乎有点复杂,因为它从所有 api 调用程序方法中删除了重复的重试逻辑。2. 由于 ruby​​ 无法使用参数名称访问参数,因此我必须强制约定使令牌参数成为所有“api 调用程序”方法中的第一个参数。这样我就可以在重试时用新令牌替换该参数。

如果 ruby​​ 有办法使用参数名称访问参数,那么上述设计将是一个可以接受的设计。

你能推荐一个更好的方法吗?

谢谢!PS:我可以为每个 api_invoker 传递“哈希”中的所有参数,然后使用令牌参数名称来访问它,无论它位于何处(类似于链接http://deepfall.blogspot.com/2008中提到的/08/named-parameters-in-ruby.html - 但这对我来说似乎更丑陋。

4

1 回答 1

0

使用选项 2 以避免重复 try catch 块。

于 2012-09-08T02:07:32.080 回答