serversessionというライブラリがリリースされました
これはサーバーサイドで管理するセッションを実装するためのライブラリです。今までもwai-sessionやSpockなどのようにそれぞれのフレームワーク向けに実装されたものはありましたが当然使い方がそれぞれ異なるという欠点がありました。しかし今後はserversessionを使うことで統一的に扱うことが出来るようになります。さらにserversessionはセッションのロジックを実装するところをfrontend、セッションを管理するところをbackendとして分離しているので目的にあった技術を組み合わせて使うことが出来ます。今あるのは
- frontend
- backend
といったライブラリでこれらを好きに組み合わせて好きな構成でセッション機能を実装することが出来ます。今回はfrontendにwaiをbackendにredisを使ってwai-sessionのexampleを書きなおしてみました。
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Monad (when)
import qualified Data.Vault.Lazy as Vault
import Data.ByteString.Char8 (ByteString, pack)
import Data.ByteString.Lazy.Char8 (fromStrict)
import Data.Text (Text)
import Network.Wai
import Network.Wai.Session (Session)
import Network.Wai.Handler.Warp (run)
import Network.HTTP.Types (ok200)
import Web.ServerSession.Frontend.Wai (withServerSession)
import Web.ServerSession.Backend.Redis (RedisStorage(..))
import qualified Database.Redis as Redis
app :: Vault.Key (Session IO Text ByteString) -> Application
app session env = (>>=) $ do
u <- sessionLookup "u"
when (["favicon.ico"] /= pathInfo env) $
sessionInsert "u" insertThis
pure $ responseLBS ok200 [] (maybe "Nothing" fromStrict u)
where
insertThis = pack . show $ pathInfo env
Just (sessionLookup, sessionInsert) = Vault.lookup session (vault env)
main :: IO ()
main = do
key <- Vault.newKey
conn <- RedisStorage <$> Redis.connect Redis.defaultConnectInfo
session <- withServerSession key id conn
run 3000 . session . app $ key
適当なパスのURLにアクセスするとアクセスするたびに前回アクセスしたパスが表示されるようなデモです。ブラウザが勝手に/favicon.ico
を見に行くのでこれは記録しないように修正しています。