Posted at

Faraday middlewareの作り方

More than 3 years have passed since last update.

Faraday middlewareの要件としては、Rack middleware同様に



  • #initialize(app)で他のmiddlewareを引数にとる


  • #call(env)でリクエストの前処理を実装する。

の2点だけを満たせばいい。ただし、レスポンスを処理する場合は#on_complete内のブロックで実装する必要がある。

def call(request_env)

@app.call(request_env).on_complete do |response_env|
# パースなどレスポンスの処理
end
end

ここまではREADME.mdにも書いてあるのだけど、レスポンスの処理を効率的に実装するための方法が用意されている。それはFaraday::Response::Middlewareだ。使い方は以下の通り。

require "faraday"

module Faraday
class Response
class JSON < Middleware
def parse(body)
body.to_json
end
end

register_middleware json: JSON
end
end



  • #initialize(app)@app = appのようなことをしているため、特に書く必要はない。特別になにか必要であればoverrideする。


  • #parse(body)でレスポンスをパースの処理を書くと、上述した#on_completeのブロックの中でこのメソッドが呼ばれ、env.body#parse(body)の結果によって更新する。

  • パース以外にレスポンス時の処理を記述したい場合、#on_completeを実装する。このメソッドは上述の#on_completeのブロック内で呼ばれるのだけど、これを実装すると#parseが呼ばれないので注意。


  • Faraday::Response.register_middlewareでキーとミドルウェアを登録できる。このキーを使って以下のように:jsonとミドルウェアを指定できる。

connection = Faraday.new do |connection|

connection.response :json
connection.adapter Faraday.default_adapter
end


簡単なのでFaraday::Response::Middlewareのソースコードを見てみる。

module Faraday

class Response
class Middleware < Faraday::Middleware
def call(env)
@app.call(env).on_complete do |environment|
on_complete(enrivonment)
end
end

def on_complete(env)
env.body = parse(env.body) if respond_to?(:parse) && env.parse_body?
end
end
end
end



  • #on_completeブロック内でMiddleware#on_completeが呼ばれていることがわかる。

  • さらにその中で#parseが実装されていれば呼ぶようになっている。

module Faraday

class Middleware
extend MiddlwareRegistry

# ...

def initialize(app = nil)
@app = app
end
end
end



  • #initializeであとに続くmiddlewareを取り込んでいる。


  • Faraday::MiddlewareRegistryというモジュールで.register_middlewareが定義されており、このメソッドでFaraday middlewareを指定する際のキーを登録できる。