[Rails]自建外站API獲取資料
因為開發上的需要,需要把一些資料放在外站,而不是原本的程式碼中。最一開始的做法是透過Ajax送出資料,跟後端取得資料後渲染在前端。
現在則是改成在透過ajax觸發特定method,在method內部再送出request到其他url,得到需要的資料後再送回前端。
步驟及預計達成的效果
- 前端送出ajax request
- 後端controller得到請求,根據資料向外站送出request
- 外站根據資料處理後回傳
- controller得到資料後回傳json格式給前端
- 前端根據得到的資料渲染
AJAX程式碼
$.get({
url: '/users/some_action.json',
data: { amount, period_in_month }
}).done(({ max, min }) => {
$('#low-fee').text(min);
$('#high-fee').text(max);
});
觸發ajax後,前端便會送出請求到對應的路徑。
後端程式碼
在開始討論之前,我們預設外站會回傳類似以下的資料
"{\"status\":\"SUCCESS\",\"message\":\"Get fee\",\"max\":10000,\"min\":100}"
以下先列出程式碼,然後一一解析每一個步驟。
def some_action
uri = URI('https://example.com/specific_controller/get_something')
fee_params = {amount: params[:amount], period_in_month: params[:period_in_month] }
uri.query = URI.encode_www_form(fee_params)
response_body = Net::HTTP.get_response(uri).body
max = JSON.parse(response_body)["max"]
min = JSON.parse(response_body)["min"]
@fee_range = { max: max, min: min}
respond_to do |format|
format.html
format.json { render json: @fee_range }
end
end
一開始讓我們定義外站的網址,這樣我們就可以在即使不知道外站程式碼的情況下,依舊可以得到我們想要的資料。
uri = URI('https://example.com/specific_controller/get_something')
這其實就像是很多第三方API的做法一樣,你只要傳指定格式的資料,API就會回傳特定的值給你。
接著定義一個params,待會我們要將這些params加到url上(query parameter)。
fee_params = {amount: params[:amount], period_in_month: params[:period_in_month] }
如果想在uri後方加上query string,可以首先透過encode_www_form這個方法來設定query string。
query_string = URI.encode_www_form("q" => "ruby", "lang" => "en")
=> "q=ruby&lang=en"
接著透過uri.query在原先定義好的uri中塞入query string。
uri.query = query_string
假設一開始我們的uri是 www.example.com ,塞入query string後會變成 www.example.com?q=ruby&lang=en
接著透過送出request到特定的路徑,並得到回傳的body
Net::HTTP.get_response(uri).body
回傳的資料是字串,所以們需要用到JSON.parse幫我們把得到的字串轉換成json格式
response_body
#=> "{\"status\":\"SUCCESS\",\"message\":\"Get fee\",\"max\":10000,\"min\":100}"
JSON.parse(response_body)
#=> {"status"=>"SUCCESS", "message"=>"Get loan fee", "max"=>10000, "min"=>100}
max = JSON.parse(response_body)["max"]
min = JSON.parse(response_body)["min"]
最後我們將到的資料存進variable中,並透過json格式傳回。
@fee_range = { max: max, min: min}
respond_to do |format|
format.html
format.json { render json: @fee_range }
end
參考資料:
@linjiahung, 就知道你写文很有潜力!