Yesod Advent Calendar 2016の2日目の記事です。Yesodに関する有用な記事が集まってきて、嬉しい限りです!
さて
JavaのServletAPIにはFilterという便利な機能があります。
これは特定のパターンのURLへのリクエストをフックし、本来の処理の前後に処理を挟んだり、場合によっては本来の処理を行わずに別の処理を実施したります。
これにより、業務的なロジックとWeb的なロジックを分離し、それぞれの処理をスッキリ実装することが出来るようになります。
Yesodでもこの機能はあり、Yesod Middleware
・・・と呼ぶようです。
(syocyさんからのご指摘で Middleware → Yesod Middlewareと改めました)
ただ、URLのパターンを指定することは出来ないようで、その辺りは自分で実装する必要があるようです。
Middlewareの作り方
Middlewareは、特に型クラスが提供されているわけではないようですが、以下のような手順で作ることが出来ます。
- ある型の関数を作る
- 1で作った関数を
Foundation.hs
の決まった場所に追記する
以下は例です。
customMiddleware :: HandlerT site IO res -> HandlerT site IO res
-- Yesod Middleware allows you to run code before and after each handler function.
-- The defaultYesodMiddleware adds the response header "Vary: Accept, Accept-Language" and performs authorization checks.
-- The defaultCsrfMiddleware:
-- a) Sets a cookie with a CSRF token in it.
-- b) Validates that incoming write requests include that token in either a header or POST parameter.
-- For details, see the CSRF documentation in the Yesod.Core.Handler module of the yesod-core package.
yesodMiddleware = defaultCsrfMiddleware . defaultYesodMiddleware . customMiddleware
Middlewareの使いどころ
基本的な考え方は「Webアプリの全リクエストに挟みたい処理」となります。例えば・・・
- 特定のクッキーがセットされていることをチェックし、無ければ認証画面にリダイレクトする
- CSFR(クロスサイトリクエストフォージェリ)対策のトークンをチェックする
実はこのMiddlewareはYesodが標準で提供していて、Foundation.csにはデフォルトで設定されています。Yesod Advent Calendar 2016の2日目の記事も参照してみて下さい。
Middleware内でDBアクセスを行うなら型宣言に注意
Middlewareの中でDBにアクセスする場合は型宣言に追記が必要になります。
dbAccessMiddleware :: (YesodPersist site, YesodPersistBackend site ~ SqlBackend) =>
HandlerT site IO res -> HandlerT site IO res