こんにちは、久保田です。
今回はRubyのHTTPクライアント、Faradayのmiddlewareの作り方をご紹介しようと思います。
RubyKaigi2016のToru KawamuraさんのWeb Clients for Ruby and What they should be in the future の発表に触発されました。
FaradayはRack同様、middlewareを作り独自の機能を追加することができます。
このmiddlewareの機能を作ることで、リクエスト、レスポンスの処理をFaradayの中に隠蔽することが可能になります。
middlewareの作り方
middlewareの作り方は、
Faraday::Middleware
を継承したクラスを実装register_middleware
メソッドを使ってmiddlewareとしてクラスを登録する。
この2ステップで作ることができます。
そしてFaradayのインスタンスを作る時に宣言することで使用することができます。
Faraday::Middleware
を継承したクラスを実装
まず、リクエストをhookするためには、
class Foo < Faraday::Middleware def call(req_env) # リクエスト時に動く end end
最低限これだけあればOKです。
callの引数にリクエスト時にFaradayが生成した変数のセットが入っており、それを書き換えることなどができます。
そして、レスポンスをhookするためには、
class Foo < Faraday::Middleware def call(req_env) # リクエスト時に動く ... @app.call(req_env).on_complete do |res_env| # レスポンスが返ってきたらコールバックされる end end end
これでOKです。
@app.call(req_env).on_complete
にブロックを渡すことで、レスポンスが返ってきた時にコールバックされるブロックを定義できます。
@app
はFaradayが定義しています。
register_middleware
メソッドを使ってmiddlewareとしてクラスを登録する。
middlewareができたらmiddlewareとして、Faradayに登録します。
この時の登録の方法でmiddlewareをリクエスト時に使えるものにするか、レスポンスが返ってきた時に使えるものにするか、両方で使うかが決まります。
そしてmiddlewareの使用時に使うメソッドも変わってきます。
正しいものを選びましょう。
リクエスト時のみ
Faraday::Request.register_middleware(foo: Foo)
使用時
connection = Faraday.new('http://example.com') do |conn| conn.request :foo end
レスポンス時のみ
Faraday::Response.register_middleware(foo: Foo)
使用時
connection = Faraday.new('http://example.com') do |conn| conn.response :foo end
両方
Faraday::Middleware.register_middleware(foo: Foo)
使用時
connection = Faraday.new('http://example.com') do |conn| conn.use :foo end
以上になります。 この機能を使って綺麗なAPI用のクライアントや、スクレイピングする機能を開発していきたいですね。
今回参考にしたのは、こちらのGemです。
https://github.com/lostisland/faraday_middleware