Haskell

serversessionを使ってみた

More than 3 years have passed since last update.

serversessionというライブラリがリリースされました :tada:

これはサーバーサイドで管理するセッションを実装するためのライブラリです。今までもwai-sessionSpockなどのようにそれぞれのフレームワーク向けに実装されたものはありましたが当然使い方がそれぞれ異なるという欠点がありました。しかし今後はserversessionを使うことで統一的に扱うことが出来るようになります。さらにserversessionはセッションのロジックを実装するところを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を見に行くのでこれは記録しないように修正しています。