[Rails]自建外站API獲取資料

in #rails6 years ago (edited)

因為開發上的需要,需要把一些資料放在外站,而不是原本的程式碼中。最一開始的做法是透過Ajax送出資料,跟後端取得資料後渲染在前端。

現在則是改成在透過ajax觸發特定method,在method內部再送出request到其他url,得到需要的資料後再送回前端。

步驟及預計達成的效果

  1. 前端送出ajax request
  2. 後端controller得到請求,根據資料向外站送出request
  3. 外站根據資料處理後回傳
  4. controller得到資料後回傳json格式給前端
  5. 前端根據得到的資料渲染

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

參考資料: