2013-03-04 79 views
8

我有一個Ruby on Rails與mvc框架的應用程序。截至目前,我在控制器中有API調用,但不認爲這是他們的正確位置。我的所有API調用都應該使用哪種文件?謝謝在Rails MVC框架項目中,API調用在哪裏發生?

def getDetails(id) 
api_response = HTTParty.get(base_uri, :query => {:DID => id, :DeveloperKey => devKey}) 
@json_hash = api_response.parsed_response 
return @json_hash 
end 
+0

「API調用」是什麼意思? – 2013-03-04 16:03:18

+0

請提供您所關心的控制器代碼示例。 – thisfeller 2013-03-04 16:05:27

+0

如果他們是外部API調用,我的想法是他們應該被視爲數據並放在模型中。這樣,您可以輕鬆添加到數據庫(用於節流)並保留SoC。只是我的想法,雖然我已經看到外部調用作爲lib中的聲明類。 – Nic 2013-03-04 16:05:44

回答

4

通過我的編碼風格(以及對MVC的理解),外部調用將被放置在「無表」模型中。 RailsCasts 193對這個概念進行了一些討論,並且在Rails 4中支持一種不太笨拙的語法。如果您需要對代碼進行任何操作,該模型似乎是放置這些概念的合理位置。將這些方法移到控制器中可能會有效,但隨着應用程序的增長可能會產生問題。

另一個考慮因素與外部API調用實際存儲那些在數據庫中,這絕對應該是一個模型在這一點上,所以(我)就變得更清晰,這些確實應該是在模型中。

+0

Rails 3已經更好地支持無表模型。耶胡達卡茨[寫了一篇很好的博客文章](http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord/)。 – 2013-03-04 17:01:53

+0

「無表模式」使得聽起來像你會用API封裝解決大量不必要的代碼。 (驗證?屬性?等)只需使用PORO。 (普通老紅寶石對象)。你爲什麼不需要上課? – 2016-11-25 16:41:53

11

對外部服務(第三方)的API調用並非特定於您的應用,因爲他們的服務對所有人都是可用的(理論上)。我的理解是,這些功能位於lib/目錄中,因爲它們不是應用程序特定的。理想情況下,您可以從項目中的lib中提取代碼,然後將其拖放到其他項目中的其他人的lib/中,該代碼仍然可以正常工作。請撥lib/。如果你願意,你可以從你的控制器中返回的數據創建一個模型。

這將是這個樣子:

應用程序/控制器/

class YourController < ApplicationController 

    def getDetails 
    # keep in mind, api call may fail so you may want surround this with a begin/rescue 
    api_response = YourApiCall.new.get_details(params[:id]) 
    # perhaps create a model 
    @model = SomeModel.new(fname: api_response[:first_name], lname: api_response[:last_name]) 
    # etc... 
    end 
end 

的lib/

require 'HTTParty' 

Class YourApiCall 
    def get_details(id) 
    HTTParty.get(base_uri, :query => {:DID => id, :DeveloperKey => devKey}) 
    @json_hash = api_response.parsed_response 
    return @json_hash 
    end 
end 
+0

嘗試過,但班級沒有加載。我最終只是把它放在模型中。另一個問題(除非我錯了)是你在聲明中的'class'中使用了C的大寫字母。 – 2014-03-15 16:22:44

+0

要加載/ lib目錄中的文件,請將以下內容添加到'config/application.rb':'config.autoload_paths + =%W(#{config.root}/lib)'。查看http://edgeguides.rubyonrails.org/configuring.html#configuring-rails-components以獲取更多信息。 – Teisman 2015-04-23 19:26:58

+0

您也可以通過將'require'your_api_call'放入要加載的控制器的頂部來加載該類 – 2015-10-21 16:11:26

4

很晚這一個,但想到我會添加我的2P/2C。

我想盡量保持我的控制器乾淨的從控制器代碼,這是我基於請求類型和參數鬆散定義爲程序流程的任何代碼分開。例如,根據用戶是否登錄,爲請求類型選擇正確的模板或選擇正確的方法來調用。

當涉及到計算的迴應,我不喜歡垃圾有很多操縱模型,並設置實例參數代碼控制器。這很難測試,甚至更難以重複使用。我更願意推遲到另一個對象,並將單個值對象返回給模板。

有時候,我可以推遲到模型:也許這是一個簡單的查找,我剛剛發送的單一模式到模板,或模型數組。

也許我已經在模型中實現了一個有用的方法來返回適當的值或值對象。

不過有時我做的東西,不使用模型,或者使用幾種模式,或者說感覺並不像它實際上應該被搞亂了模型。在這種情況下,控制器和模型都不適用於代碼。

lib目錄感覺不對。我傾向於將lib目錄視爲包含代碼的地方,但我還沒有被困擾成爲寶石。如果我正在編寫的代碼在應用程序的上下文中是有意義的,那麼它並不好。

所以我轉向服務對象。在'app'文件夾下,我有一個'services'文件夾,其中包含封裝單個網站行爲塊的小型功能類。 (或者有時,協調其他幾項服務,爲控制器提供一個簡單的接口。)

這使我可以輕鬆控制我的控制器和我的模型,並且可以放置需要聯繫API的代碼。

如果您想更進一步,您可以將API本身封裝在一個包裝類(或一組類)中,並將它們保存在lib目錄中(可能在稍後的日期轉換爲gem)。然後,服務對象將執行使用適當的值(從控制器傳遞)調用API包裝的任務,並使用模板可以乾淨地詢問的內容進行響應。

當然,你可以走得更遠,並添加更多的圖層。例如,表示層可以位於服務對象(提供通用值)和特定視圖的格式數據之間。 (也許你想提供一個網頁和一個RSS源,他們需要不同的日期格式)

但你明白了。