見出し画像

Faradayについて調べてみました。

概要

FaradayはHTTP Clientライブラリです。
多くのアダプタに対して共通のインターフェースを提供し、リクエスト/レスポンスサイクルを処理する際にRackミドルウェアの概念を取り入れたHTTPクライアントです。

getting started

最初はfaraday_githubを見よう! 
もっと詳しいことを知りたい時はrubydocを見てね!

使用方法

まず最初に、どのアダプタを使いたいかをFaradayに伝える必要があります。
アダプタは実際にHTTPリクエストを実行する役割を担っています。
たくさんの種類のアダプタがあります。好きなものを選んでインストールするか、プロジェクトのGemfileに追加してください。
アダプタについて詳しくなりたい場合はAdaptersを見てください

関連するアダプターをインストールする必要があります。
例:net_httpの場合

require 'faraday'
require 'faraday/net_http'
Faraday.default_adapter = :net_http

Faraday.getを使用してGETリクエストを行う方法

response = Faraday.get('http://httpbingo.org')

レスポンスステータス、ヘッダー、ボディーをもったオブジェクト(Faraday::Response)を返します。

response.status
# => 200

response.headers
# => {"server"=>"Fly/c375678 (2021-04-23)", "content-type"=> ...

response.body
# => "<!DOCTYPE html><html> ...

Faraday Connection

Faradayを使う場合、特にサードパーティのサービスやAPIと連携する場合は、Faraday::Connectionを作成することが推奨されています。
接続オブジェクトは、以下のような構成にすることができます。
・デフォルトのリクエストヘッダとクエリパラメータ
・プロキシやタイムアウトなどのネットワーク設定
・共通URLのベースパス
・Faraday adapter & middleware(後述)
Faraday.newを呼び出してFaraday::Connectionを作成します。そして、作成したFaraday::Connectionに対して、各HTTP動詞(get, post, ...)を呼び出してリクエストを実行することができます。

conn = Faraday.new(
  url: 'http://httpbingo.org',
  params: {param: '1'},
  headers: {'Content-Type' => 'application/json'}
)

response = conn.post('/post') do |req|
  req.params['limit'] = 100
  req.body = {query: 'chunky bacon'}.to_json
end
# => POST http://httpbingo.org/post?param=1&limit=100

GET, HEAD, DELETE, TRACE

Faradayは、通常リクエストボディを含まない、以下のHTTP動詞をサポートしています。

get(url, params = nil, headers = nil)
head(url, params = nil, headers = nil)
delete(url, params = nil, headers = nil)
trace(url, params = nil, headers = nil)

リクエスト時にURLのクエリパラメータやHTTPヘッダを指定することができます。

response = conn.get('get', { boom: 'zap' }, { 'User-Agent' => 'myapp' })
# => GET http://httpbingo.org/get?boom=zap

POST, PUT, PATCH

Faradayはまた、bodyを持つHTTP動詞をサポートしています。クエリパラメータの代わりに、これらはリクエストボディを受け付けます。

post(url, body = nil, headers = nil)
put(url, body = nil, headers = nil)
patch(url, body = nil, headers = nil)

# POST 'application/x-www-form-urlencoded' content
response = conn.post('post', 'boom=zap')

# POST JSON content
response = conn.post('post', '{"boom": "zap"}', "Content-Type" => "application/json")

Posting Forms
Faradayは、デフォルトの接続に含まれるurl_encodedミドルウェアのおかげで、key/valueハッシュを自動的に適切なフォームボディに変換してくれます。

# POST 'application/x-www-form-urlencoded' content
response = conn.post('post', boom: 'zap')
# => POST 'boom=zap' to http://httpbingo.org/post

Detailed HTTP Requests

Faradayはリクエストを行うための長いスタイルをサポートしています。これは、デフォルトの多くを変更する必要がある場合や、HTTP リクエストの詳細がメソッドの引数によって変化する場合に便利です。HTTP動詞ヘルパーのそれぞれは、送信前に修正可能なFaraday::Requestを生成することができます。
この例では、JSONリクエストボディを実際の検索クエリとして受け入れる仮想的な検索エンドポイントを示しています。

response = conn.post('post') do |req|
  req.params['limit'] = 100
  req.headers['Content-Type'] = 'application/json'
  req.body = {query: 'chunky bacon'}.to_json
end
# => POST http://httpbingo.org/post?limit=100

Customizing the Request

コネクション時の設定や、リクエストに応じた調整が可能です。
コネクション時

conn = Faraday.new('http://httpbingo.org', request: { timeout: 5 })
conn.get('/ip')

リクエストに応じたオプション

conn.get do |req|
  req.url '/ip'
  req.options.timeout = 5
end

また、contextオプションを使えば、任意のデータをリクエストに注入することも可能です。すべてのミドルウェアの env で利用できるようになります。

conn.get do |req|
  req.url '/get'
  req.options.context = {
    foo: 'foo',
    bar: 'bar'
  }
end

Changing how parameters are serialized

時には、同じ URL のパラメータを異なる値で複数回送信する必要があります。
この場合、パラメータエンコーダーを手動で設定する必要があり、 コネクションごとあるいはリクエストごとに設定することができます。
これはすべての HTTP 動詞に適用されます。

コネクション事に設定する場合

conn = Faraday.new request: { params_encoder: Faraday::FlatParamsEncoder }
conn.get('', { roll: ['california', 'philadelphia'] })

リクエスト事に設定する場合

conn.get do |req|
  req.options.params_encoder = Faraday::FlatParamsEncoder
  req.params = { roll: ['california', 'philadelphia'] }
end

Custom serializers

お好みでカスタムエンコーダを作ることができます。
Faraday params_encoderの値は、これに応答する任意のオブジェクトにすることができます。

#encode(hash) #=> String
#decode(string) #=> Hash

エンコーダは、Faraday がクエリ文字列を処理する方法と POST ボディをシリアライズする方法の両方に影響を及ぼします。
デフォルトのエンコーダは Faraday::NestedParamsEncoder です。

Proxy

FaradayはURI#find_proxyを使って、あなたのシステムから自動的にプロキシ設定を推測しようとします。 これはhttp_proxy, ftp_proxy, no_proxyなどの環境変数からそれらを取得します。 何らかの理由でこの動作を無効にしたい場合は、グローバル変数 ignore_env_proxy を設定することで可能です。
また、コネクションの初期化時にカスタムプロキシーを指定することもできます。

conn = Faraday.new('http://www.example.com', proxy: 'http://proxy.com')

Streaming Responses

時には、streaming応答を受け取る必要があるかもしれません。これは on_data リクエストオプションで行うことができます。
on_dataコールバックは、チャンク文字列のタプルと、これまでに受信したバイトの合計を受け取ります。
これはコールバックの実装例:

# A buffer to store the streamed data
streamed = []

conn.get('/stream/10') do |req|
  # Set a callback which will receive tuples of chunk Strings
  # and the sum of characters received so far
  req.options.on_data = Proc.new do |chunk, overall_received_bytes|
    puts "Received #{overall_received_bytes} characters"
    streamed << chunk
  end
end

# Joins all response chunks together
streamed.join

on_data streamingは、現在いくつかのアダプタでのみサポートされています。どれが対応しているかは、Awesome Faraday の比較表を参照するか、アダプタのドキュメントを確認してください。

Adapters

Faraday Adapter インターフェースは、Faraday のリクエストがどのように Faraday のレスポンスオブジェクトに変換されるかを決定します。
アダプタは一般的な Ruby HTTP クライアントで実装されますが、カスタム実装も可能です。
アダプタはグローバルに、あるいはFaraday Connectionごとに設定ブロックを通して設定することができます。

Fantastic adapters and where to find them

唯一の例外はテスト用のアダプターで、ファラデーとは別に配布されています。アダプタは通常 gems として提供されるか、HTTP クライアントにバンドルされています。
ほとんどのアダプタは一般的な Ruby HTTP クライアントライブラリを使用していますが、 完全にカスタマイズされた実装を持つこともできます。
もしあなたがこれから始めるのであれば、Awesome Faraday で注目のアダプタの一覧を見ることができます。誰でもFaradayのアダプタを作成し、配布することができます。もし、もっと学びたいのであれば、自分で作る方法をチェックしてみてください。

Ad-hoc adapters customization

Faraday は、あなたのコードとアダプタの間の汎用的なインターフェイスであることを意図しています。
しかし、時には Faraday のインターフェイスではカバーしきれない、あるアダプタに固有の機能にアクセスする必要があります。
そんなときは、アダプタを指定するときにブロックを渡してカスタマイズすることができます。ブロックのパラメータは、使用しているアダプタによって変わります。詳しくは各アダプタのページをご覧ください。

この記事が気に入ったらサポートをしてみませんか?