LoginSignup
5
1

More than 5 years have passed since last update.

YesodでリクエストをフックするにはYesod Middlewareを使う

Last updated at Posted at 2016-12-09

Yesod Advent Calendar 2016の2日目の記事です。Yesodに関する有用な記事が集まってきて、嬉しい限りです!

さて
JavaのServletAPIにはFilterという便利な機能があります。
これは特定のパターンのURLへのリクエストをフックし、本来の処理の前後に処理を挟んだり、場合によっては本来の処理を行わずに別の処理を実施したります。

middleware.png

これにより、業務的なロジックとWeb的なロジックを分離し、それぞれの処理をスッキリ実装することが出来るようになります。

Yesodでもこの機能はあり、Yesod Middleware ・・・と呼ぶようです。
(syocyさんからのご指摘で Middleware → Yesod Middlewareと改めました)

ただ、URLのパターンを指定することは出来ないようで、その辺りは自分で実装する必要があるようです。

Middlewareの作り方

Middlewareは、特に型クラスが提供されているわけではないようですが、以下のような手順で作ることが出来ます。

  1. ある型の関数を作る
  2. 1で作った関数を Foundation.hs の決まった場所に追記する

以下は例です。

customMiddleware :: HandlerT site IO res -> HandlerT site IO res
Foundation.hs
    -- 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
5
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1