要用 Faraday 還是 Net HTTP 呢?

紅寶鐵軌客
來關注...
關注/停止關注:紅寶鐵軌客
關注有什麼好處?:當作者有新文章發佈時,「思書」就會自動通知您,讓您更容易與作者互動。
現在就加入《思書》,你就可以關注本作者了!
《思書》是一個每個人的寫作與論壇平台,特有的隱私管理,讓你寫作不再受限,討論更深入真實,而且免費。 趕快來試試!
還未加入《思書》? 現在就登錄! 已經加入《思書》── 登入
寫程式中、折磨中、享受中 ......
1.36k   0  
·
2018/11/22
·
5分鐘


在 Rails 或是 Ruby 中,少不了要讀寫網路資料,大家最熟悉的應該就是 Net::HTTP,下面就是一段很典型的 Net:HTTP code

Net::HTTP.start(uri.host, uri.port, :read_timeout => 2, :open_timeout => 2, :use_ssl => v_use_ssl) do |http|
# 很多參數....
  begin
    resp = http.get(uri.path)
    # 當然要用 rescue,網路一定會有問題
    case resp
    when Net::HTTPSuccess then
      # 成功...
      # 來做些事
    else
      # 失敗,有很種理由...
    end

  # 網路讀取失敗
  rescue
    # 失敗要做什麼?
  end
  # ^ of begin/rescue
end

使用 Net:HTTP 沒什麼不對,但是久了,你就會看到有人用 Faraday,問題來了,為什麼「他們」要用 Faraday? Faraday 又是什麼呢?

原來有這麼多種 HTTP clients 

在 Ruby Toolbox 中,有列出了最少 25 個 HTTP clients,這些 HTTP clients 基本上都有不同的使用理由,排名前幾名的,大概可以先分成以下這幾種:

  • Net: HTTP 是最基本的,Ruby 的內建 library,但是使用起來可能有很多細節要注意,例如:如果要存取 SSL 就要設定 net.use_ssl = true,不然就出現 exception error。
  • 把 Net:HTTP 包起來,讓開發更方便,這裡面有名的有:
    • excon
    • httparty
    • rest client
  • Faraday 的特色是他是一個介面,用它可以自由選擇那種 HTTP clients,這樣寫好的程式以後如果要換 HTTP clients 就不用改寫。
  • Typhoeus 是個多執行緒 (Multi-Threading) client,也就是他可以多工處理,理論上會有效率些。
  • HTTP.rb 有很好的 streaming 功能,是個很好的明日之星。
所以各有優缺點,那我要用那個呢?

我覺得初學的人,還是要用 Net:HTTP, 原生的 Ruby library,好處是網路上有很多的參考資料,容易找到問題,對學習者是很重要的,用 Net:HTTP 會要處理很多細節,但是這也是重要的學習過程。

lostisland/faraday — Simple, but flexible HTTP client library, with support for multiple backends. - lostisland/faraday
GitHub

實務上選擇,我覺得 Net:HTTP 還是一個首選,畢竟,以後找人維護比較方便,但是如果考量到未來改變的可能性,Faraday 就是一個很好的選擇,它也是 Ruby toolbox 列表中排第一名的,畢竟,如果將來需要改用其他的 client,Faraday 只要用以下一行指令就好:

Faraday.default_adapter = :typhoeus

這樣,你的程式就是用 typhoeus 變成多執行緒了,Farady 也可以省下很多碼,少打些字,對熟悉的工程師,會省些開發時間更 debug。還有一個好處是,換其他的 HTTP clients 後,連 exceptions 都不用改,Faraday 會作轉換。

Faraday 的文件還真是很長,有空是一定要好好看看啦,但是我是很健忘的人,還好,網路上總是有很多好心人,以下就是我找到由 mislav 在 GitHubGist、及、「我的跟我找到的其他人寫的」作弊單:

Faraday SSL example — Faraday SSL example. GitHub Gist: instantly share code, notes, and snippets.
Gist

connection = Faraday::Connection.new('http://example.com') do |builder|
  builder.request :url_encoded  # for POST/PUT params
  builder.adapter :net_http
end

# same as above, short form:
connection = Faraday.new 'http://example.com'

# GET
connection.get '/posts'

# or, with timeout/open_timeout
conn = Faraday::Connection.new
conn.options.timeout = 5 # in seconds,
conn.options.open_timeout = 5 # in seconds
resp = conn.get('http://example.com/get')

# POST payload
payload = {:title => 'Example'}
connection.post '/posts', payload

# use middleware for JSON, and set FollowRedirects (這好用!)
require 'faraday_middleware'
client = Faraday.new do |f|
  f.use FaradayMiddleware::FollowRedirects, limit: 3
  f.response :json
  f.options.timeout = 20
  f.options.open_timeout = 10
  #faraday.use :cookie_jar
  # adapter is critical... must have
  #f.adapter :net_http
  f.adapter Faraday.default_adapter
end
client.get('https://api.github.com/repos/vmg/redcarpet/issues')

# set the request header
conn = Faraday.new(url: 'http://www.bunyons.com')
conn.post do |req|
  req.url '/dave/onion'
  req.headers['Referer'] = 'http://www.something.com'
  req.headers['User-Agent'] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"
  req.headers['X-Forwarded-For'] = '86.185.170.5'
  req.headers['X-Requested-With'] = 'XMLHttpRequest'
  req.body = { plasticpantsid: 2403, arbitudeabuthnot: 'faff' }
end

# another way using middleware 
url = 'https://api.spotify.com/v1'

conn = Faraday.new(url: url) do |faraday|
  faraday.adapter Faraday.default_adapter
  faraday.response :json
end

response = conn.get('search', type: 'artist', q: 'tycho')
response.body

# now again, over SSL
# verify_mode is automatically set to OpenSSL::SSL::VERIFY_PEER
connection = Faraday.new 'https://example.com'

# turn off SSL
# (no use-case for this, really)
connection = Faraday.new 'https://example.com', :ssl => false

# turn off peer verification
connection = Faraday.new 'https://example.com', :ssl => {:verify => false}
# Faraday 官網上不建議,這會讓 encryption 弱化。

# other SSL options
connection = Faraday.new 'https://example.com', :ssl => {
    :client_cert  => ...,
    :client_key   => ...,
    :ca_file      => ...,
    :ca_path      => ...,
    :cert_store   => ...
  }
其他還有一些可以考慮的 HTTP clients:
httparty

jnunemaker/httparty — :tada: Makes http fun again! Contribute to jnunemaker/httparty development by creating an account on GitHub.
GitHub

目前 Ruby toolbox 星星最多的,4,697 星,比 faraday 都高,好處就是簡單方便好用,就像他的名稱一樣,好用到像是開 party,如果只是使用簡單的 HTTP 功能,這個真的是很方便,強烈建議.

require 'httparty'
response = HTTParty.get('http://example.com')
# 省了 get_response,也不用ssl
response.code
# 200
response.parsed_response
# 連 JSON 都處理好了
http.rb

httprb/http — HTTP (The Gem! a.k.a. http.rb) - a fast Ruby HTTP client with a chainable API, streaming support, and timeouts - httprb/http
GitHub

這個 client 非常的吸引我,我幾乎就要改用它了,最主要就是他所說的效能:

HTTP client Time Implementation
curb (persistent) 2.519 libcurl wrapper
em-http-request 2.731 EM + http_parser.rb
Typhoeus 2.851 libcurl wrapper
StreamlyFFI (persistent) 2.853 libcurl wrapper
http.rb (persistent) 2.970 Ruby + http_parser.rb
http.rb 3.588 Ruby + http_parser.rb
HTTParty 3.931 Net::HTTP wrapper
Net::HTTP 3.959 Pure Ruby
Net::HTTP (persistent) 4.043 Pure Ruby
open-uri 4.479 Net::HTTP wrapper
Excon (persistent) 4.618 Pure Ruby
Excon 4.701 Pure Ruby
RestClient 26.838 Net::HTTP wrapper

上面這個表是我從它的 Gem 說明中 copy 下來的,效能竟然比原生的 Net:HTTP 好,很接近以 libcurl 為基礎的 client,再加上,他有非常好的 streaming 能力,要不是它不能跟 Faraday 連接,幾乎完美,如果對上傳下載有需求的開發,我一定會考慮用這個的,有一篇 Http.rb is Great - By Janko Marohnić HTTP.rb 有很詳細的說明,有興趣的讀者可以參考。

rest-client

目前 Ruby toolbox 星星第二多,4,520 星,跟 HTTParty 一樣算簡單好用的,但是要另外處理 JSON,我覺得要用這個不如用 httparty,又加上效能好像不好,除非你跟 Sinatra 很熟,用這個的理由好像不高了。

Ruby 的社群真是很大,拜大家的貢獻,很幸運的有很多選擇,到底那個最合你的愛,還是要自己試用才對,有選擇真好!


喜歡作者的文章嗎?馬上按「關注」,當作者發佈新文章時,思書™就會 email 通知您。

思書是公開的寫作平台,創新的多筆名寫作方式,能用不同的筆名探索不同的寫作內容,無限寫作創意,如果您喜歡寫作分享,一定要來試試! 《 加入思書》

思書™是自由寫作平台,本文為作者之個人意見。


文章資訊

本文摘自:
分類於:
標籤:
日期:
創作於:2018/11/22,最後更新於:2018/12/15。
合計:1461字


分享這篇文章:
關於作者

很久以前就是個「寫程式的」,其實,什麼程式都不熟⋯⋯
就,這會一點點,那會一點點⋯⋯




參與討論!
現在就加入《思書》,馬上參與討論!
《思書》是一個每個人的寫作與論壇平台,特有的隱私管理,用筆名來區隔你討論內容,讓你的討論更深入,而且免費。 趕快來試試!
還未加入《思書》? 現在就登錄! 已經加入《思書》── 登入


看看作者的其他文章


看看思書的其他文章



×
登入
申請帳號

需要幫助
關於思書

暗黑模式?
字體大小
成人內容未過濾
更改語言版本?