Rack Middlewareを条件付きで実行するためのRack Middlewareを書いた
あるRackミドルウェアがあったとして、それを特定の条件下でのみ実行させたいとする。
その際には、以下に示すような回避策を講じることになる。
class SpecialMiddleware < Rack::AwesomeMiddleware
def call(env)
except?(env) ? @app.call(env) : super
end
def except?(env)
env["PATH_INFO"].start_with?("/api")
end
private :except?
end
use SpecialMiddleware
で、これはこれで良いんだけど、対象が複数個のミドルウェアになってくるとなかなかに面倒臭い。
というわけでシンプルに書けるようにするRack Middlewareを書いてみた。
上記のコードをMandrakeを使って置き換えると、以下のようなコードになる。
use Mandrake::Middleware do
# 以下のifオプションの値は実際の比較式とは異なり、それ自身を文字列にして返すメソッド。
# 内部的にはその文字列をexcept?のようなメソッドの中身として定義し条件分岐を実現している。
use Rack::AwesomeMiddleware, if: env["PATH_INFO"].start_with?("/api")
# lambdaを渡した場合には、そのブロックをそのまま条件分岐用のメソッドとして、define_methodを使って定義している。
# use Rack::AwesomeMiddleware, if: -> { env["PATH_INFO"].start_with?("/api") }
end
完成すれば軽く便利だし、面白いかなぁと思って作ってみたGem。
書いたのは大分前だけど、せっかくなので記事にした。
おわり。