我正在处理一个需要我执行以下操作的 API(无法更改 API):
- 登录服务使用它(登录)
- 使用 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 - 但这对我来说似乎更丑陋。