2016-03-07 84 views
3

这是我奋斗的一件事,或者每当我这样做的时候,它似乎是一团糟。 我会以非常普遍的方式提出问题,因为它不是我真正想要解决的单个问题。获取API中的所有页面

我有一个API,我想消费一些数据,例如,通过:

def get_api_results(page) 
    results = HTTParty.get("api.api.com?page=#{page}") 
end 

当我打电话时,我可以检索总数。

results["total"] = 237 

的API限制的记录,我可以在一个呼叫检索的数,如20,所以我需要调用它几次。

我想要做的东西像下面,最好它摔成了碎片,所以我可以用的东西像delayed_job..etc

def get_all_api_pages 
    results = get_api_results(1) 
    total = get_api_results(1)["total"] 

    until page*20 > total do |p| 
    results += get_api_results(p) 
    end 
end 

我总觉得我写垃圾,每当我试图解决这个问题(我试图用很多方法解决它)。例如,上述举例使我受到API错误的支配,如果我在任何时候出现错误,API都会将我收集的所有结果剔除。

想知道是否只有一个好的,干净的方式来处理这种情况。

+0

这里可能没有干净的解决方案;该方法根据定义是肮脏的!如果您一次请求太多的信息,某些API可能会超时,动态API可能会在通话过程中发生变化,因此当您开始时包含500个条目的集合在您完成时可能包含505(或更差,499)。寻呼API通常是分页的原因。也就是说,你所采取的方法可能是最好的,特别是对于小而动态的套件。对于更大但更静态的集合,下面的枚举方法可能会有用,特别是如果消费者不需要所有条目。 – GoGoCarl

回答

1

我不认为你可以拥有那么多的清洁剂......因为只有你调用了API才能得到总数。 您是否尝试过为此构建自己的枚举?它封装了丑陋的部分。这是一个有点示例代码以“嘲笑” API:

class AllRecords 
    PER_PAGE = 50 

    def each 
    return enum_for(:each) unless block_given? 
    current_page = 0 
    total = nil 
    while total.nil? || current_page * PER_PAGE < total 
     current_page += 1 
     page = load_page(current_page) 
     total = page[:total] 
     page[:items].each do |item| 
     yield(item) 
     end 
    end 
    end 

    private 

    def load_page(page) 
    if page == 5 
     {items: Array.new(37) { rand(100) }, total: 237} 
    else 
     {items: Array.new(50) { rand(100) }, total: 237} 
    end 
    end 
end 

AllRecords.new.each.each_with_index do |item, index| 
    p index 
end 

你一定能清除该出来了一点,但我认为这是很好的,因为它不首先收集所有的项目。

相关问题