| Safe Haskell | Safe-Inferred |
|---|---|
| Language | Haskell2010 |
Servant.API.Cookies
Description
Synopsis
- type SessionMap = Map ByteString ByteString
- type SetCookieHeader a = Headers '[Header "Set-Cookie" SetCookie] a
- data ProvideCookies (mods :: [Type])
- data WithCookies (mods :: [Type])
- data HasCookies = HasCookies
- data HasCookiesMaybe = HasCookiesMaybe
- updateCookies :: Key -> SessionMap -> SetCookie -> ByteString -> a -> IO (SetCookieHeader a)
- clearSession :: SetCookie -> a -> IO (SetCookieHeader a)
Documentation
type SessionMap = Map ByteString ByteString Source #
A SessionMap is a hash map of session data from a request.
type SetCookieHeader a = Headers '[Header "Set-Cookie" SetCookie] a Source #
A SetCookieHeader is a convenience type for adding a "Set-Cookie" header that expects a SetCookie record type.
I wanted to have the header name be NTH.hSetCookie for extra "use the known correct value" goodness, but that breaks the type magic Servant relies upon.
data ProvideCookies (mods :: [Type]) Source #
The ProvideCookies and WithCookies combinator work in tandem
together -- the ProvideCookies combinator parses the cookies from
the request and stores them in the WAI request Vault, the
WithCookies combinator provides the cookies as a hash map to the
handler.
Instances
data WithCookies (mods :: [Type]) Source #
As mentioned above, the WithCookies combinator provides
already-parsed cookies to the handler as a SessionMap.
The cookie values are assumed to be encrypted with a
Web.ClientSession.Key. Likewise, updateCookies encrypts the
cookies on the outbound side via this mechanism.
Example:
import Control.Monad.IO.Class (liftIO)
import Servant
import ServantExtras.Cookies
import qualified Data.Map.Strict as Map
type MyAPI = "my-cookie-enabled-endpoint"
:> ProvideCookies '[Required]
:> WithCookies '[Required]
:> Get '[JSON] NoContent
myServer :: Server MyAPI
myServer = cookieEndpointHandler
where
cookieEndpointHandler :: SessionMap -> Handler NoContent
cookieEndpointHandler sMap =
let mCookieValue = lookup MerlinWasHere $ Map.toList sMap in
case mCookieValue of
Nothing -> do
liftIO $ print "Merlin was *NOT* here!"
throwError err400 { errBody = "Clearly you've missed something." }
Just message -> do
liftIO $ do
print "Merlin WAS here, and he left us a message!"
print message
pure NoContent
Instances
data HasCookies Source #
HasCookies and HasCookiesMaybe are internal utitily types. You should only need to use ProvideCookies and WithCookies.
As an aside, they're separate types (rather than a single type with a (mods :: [Type]) ) phantom type because the term-level values show up in the instances, and I didn't see a clean way to separate them out by case, and only covering one value from the sum type made Haskell (rightly) complain.
Constructors
| HasCookies |
data HasCookiesMaybe Source #
HasCookies and HasCookiesMaybe are internal utitily types. You should only need to use ProvideCookies and WithCookies.
Constructors
| HasCookiesMaybe |
updateCookies :: Key -> SessionMap -> SetCookie -> ByteString -> a -> IO (SetCookieHeader a) Source #
This function takes a SessionMap and provides a "Set-Cookie" header to set the SessionData to a newly minted value of your choice.
clearSession :: SetCookie -> a -> IO (SetCookieHeader a) Source #
This function clears session data, for a fresh, minty-clean experience. The archetypal use case is when a user logs out from your server.