Ruby の HTTP クライアントライブラリ Faraday が便利そう
API ラッパの開発には RestClient gem だとか
OAuth の必要なものは Net/HTTP + OAuth gem を使ってた
Twitter gem や Instagram gem など API ライブラリのソースを読んでみると
Faraday gem というものがよく使われてた
なんとなく気になったので Faraday について調べてみた
ついでに Tumblife gem を Faraday を使うようにした
以下そのメモ
Faraday is an HTTP client lib that provides a common interface over many adapters (such as Net::HTTP) and embraces the concept of Rack middleware when processing the request/response cycle.
Faraday は HTTP クライアントライブラリ
Net::HTTP やその他の多くのアダプタに共通のインターフェースを提供し
また Rack ミドルウェアのようなインターフェースでリクエスト/レスポンスのサイクルを処理することが出来る
- Net/HTTP
- Excon
- Typhoeus
- Patron
- EventMachine
こんな感じで使える
builder.use で使用するミドルウェアを宣言する
conn = Faraday::Connection.new(:url => 'http://example.com') do |builder|
builder.use Faraday::Request::UrlEncoded # リクエストパラメータを URL エンコードする
builder.use Faraday::Response::Logger # リクエストを標準出力に出力する
builder.use Faraday::Adapter::NetHttp # Net/HTTP をアダプターに使う
end
response = conn.get '/api/nyan.json' # GET http://example.com/api/nyan.json
puts response.body
あるいは Faraday::Connection.new ... の部分はこうとも書ける
conn = Faraday.new(:url => 'http://example.com') do |builder|
builder.request :url_encoded
builder.response :logger
builder.adapter :net_http
end
また GET リクエストの送信部分もこう書くことも出来る
conn.get '/api/nyan.json', {:color => :black} # GET http://example.com/api/nyan.json?color=black
response = conn.get do |req| # GET http://example.com/api/nyan.json?color=white&size=big
req.url '/api/nyan.json', {:color => :white}
req.params[:size] = :big
end
POST はこう書く
conn.post '/api/wan.json', {:color => :black} # POST "color=black" to http://example.com/api/nyan.json
conn.post do |req|
req.url '/api/wan.json'
req.body = {
:color => :black,
:size => :big
}
end
ファイルのアップロードも出来る
conn = Faraday.new(:url => 'http://example.com') do |builder|
builder.request :multipart # マルチパートでデータを送信
builder.request :url_encoded
builder.adapter :net_http
end
params = {
:name => 'nyanco',
:picture => Faraday::UploadIO.new('nyanco.jpg', 'image/jpeg')
}
conn.put '/api/nyan.json', params
上記の他にこんなミドルウェアがある
主要(と思われる)ものだけ抜粋した
-
request
- :basic_authentication (ベーシック認証)
- :retry (リクエスト失敗時に指定回数まで再接続する)
-
response
- :raise_error (4xx, 5xx エラー時に例外を投げる)
他に FaradayMiddleware gem というナイスなライブラリがあって
これを使うと色々な便利ミドルウェアが使えるようになる
-
request
- :oauth (OAuth 対応 / SimpleAuth gem 依存)
- :oauth2 (OAuth2 対応)
-
response
- :caching (レスポンスをキャッシュする)
- :parse_json (レスポンスの JSON を Hash 形式で返す / JSON gem 依存)
- :parse_xml (レスポンスの XML を Hash 形式で返す / MultiXML gem 依存)
- :mashify (レスポンスの Hash を Hashie::Mash 形式で返す / Hashie gem 依存)
- :follow_redirects (リダイレクトを追う)
便利そうなのはこんなところか
因みにミドルウェアへパラメータを渡す時は、ミドルウェアの宣言時の第二引数以降で渡す
ミドルウェアは宣言した順番と逆に呼び出されるので書く順番には注意
conn = Faraday.new(options) do |builder|
credentials = {
:consumer_key => consumer_key,
:consumer_secret => consumer_secret,
:token => oauth_token,
:token_secret => oauth_token_secret
}
builder.request :oauth, credentials
end
その他詳しいオプションとか使い方は各公式ドキュメント見てくれ
call メソッドが実装されたクラスを作る
Faraday::Middleware を継承すると面倒見てくれるので便利
class MyMiddlewre < Faraday::Middleware
def call(env)
# リクエストに対して何かしたい場合はここに書く
@app.call(env).on_complete do
# レスポンスに対して何かしたい場合はここに書く
end
end
end
env には以下のものが Hash で入ってる
-
request phase
- :method
- :url
- :body
-
response phase
- :status
- :body
- :response_headers
レスポンスだけ弄りたい場合は Faraday::Response::Middleware を継承すれば良い
class MyResponseMiddleware < Faraday::Response::Middleware
def on_complete(env)
# レスポンスに対して何かする
end
end
因みに Tumblife gem では下記のミドルウェアを自分で拡張したので参考までに
- JSON gem の代わりに MultiJson gem で JSON をパース
- クライアントエラー(HTTP Status 4xx)時に例外を投げる
- サーバーエラー(HTTP Status 5xx)時に例外を投げる
- HTTP リクエスト部分が宣言的に美しく書ける
- リクエスト/レスポンスが柔軟に設定出来る
自分で使ってて感じたのはこのくらいか
有名な API ライブラリが使ってるから...という感じは否めない
でも慣れてきたら便利な気がする
あと OAuth / OAuth2 両方に対応してるので
API によって gem を使い分けるみたいな面倒くさいことしなくても良い
使用できるアダプターにある EventMachine がちょっと気になってる
これを使うと並列かつ非同期でリクエストが送れたりするのだろうか
クローラ等作るのに便利そうなので気が向いたら調べてみよう