2016-03-07 69 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 

你一定能清除該出來了一點,但我認爲這是很好的,因爲它不首先收集所有的項目。

相關問題