Safe Haskell | None |
---|
Web.Simple.Controller
Contents
Description
Controller
provides a convenient syntax for writting Application
code as a Monadic action with access to an HTTP request as well as app
specific data (e.g. a database connection pool, app configuration etc.)
This module also defines some
helper functions that leverage this feature. For example, redirectBack
reads the underlying request to extract the referer and returns a redirect
response:
myController = do ... if badLogin then redirectBack else ...
- newtype Controller r a = Controller (ControllerState r -> ResourceT IO (Either Response a, ControllerState r))
- runController :: Controller r a -> r -> Request -> ResourceT IO (Either Response a)
- runControllerIO :: Controller r a -> r -> Request -> IO (Either Response a)
- controllerApp :: r -> Controller r a -> Application
- controllerState :: Controller r r
- putState :: r -> Controller r ()
- request :: Controller r Request
- localRequest :: (Request -> Request) -> Controller r a -> Controller r a
- respond :: Response -> Controller r a
- requestHeader :: HeaderName -> Controller r (Maybe ByteString)
- routeHost :: ByteString -> Controller r a -> Controller r ()
- routeTop :: Controller r a -> Controller r ()
- routeMethod :: StdMethod -> Controller r a -> Controller r ()
- routeAccept :: ByteString -> Controller r a -> Controller r ()
- routePattern :: ByteString -> Controller r a -> Controller r ()
- routeName :: ByteString -> Controller r a -> Controller r ()
- routeVar :: ByteString -> Controller r a -> Controller r ()
- class Parseable a
- queryParam :: Parseable a => ByteString -> Controller r (Maybe a)
- queryParam' :: Parseable a => ByteString -> Controller r a
- queryParams :: Parseable a => ByteString -> Controller r [a]
- readQueryParam :: Read a => ByteString -> Controller r (Maybe a)
- readQueryParam' :: Read a => ByteString -> Controller r a
- readQueryParams :: Read a => ByteString -> Controller r [a]
- parseForm :: Controller r ([Param], [(ByteString, FileInfo FilePath)])
- redirectBack :: Controller r ()
- redirectBackOr :: Response -> Controller r ()
- data ControllerException
- module Control.Exception.Peel
- class ToApplication r where
- toApp :: r -> Application
- fromApp :: ToApplication a => a -> Controller r ()
- body :: Controller r ByteString
Example
The most basic Routeable
types are Application
and Response
. Reaching
either of these types marks a termination in the routing lookup. This module
exposes a monadic type Route
which makes it easy to create routing logic
in a DSL-like fashion.
Route
s are concatenated using the >>
operator (or using do-notation).
In the end, any Routeable
, including a Route
is converted to an
Application
and passed to the server using mkRoute
:
mainAction :: Controller () () mainAction = ... signinForm :: Controller () () signinForm req = ... login :: Controller () () login = ... updateProfile :: Controller () () updateProfile = ... main :: IO () main = run 3000 $ controllerApp () $ do routeTop mainAction routeName "sessions" $ do routeMethod GET signinForm routeMethod POST login routeMethod PUT $ routePattern "users/:id" updateProfile routeAll $ responseLBS status404 [] "Are you in the right place?"
newtype Controller r a Source
The Controller Monad is both a State-like monad which, when run, computes
either a Response
or a result. Within the Controller Monad, the remainder
of the computation can be short-circuited by respond
ing with a Response
.
Constructors
Controller (ControllerState r -> ResourceT IO (Either Response a, ControllerState r)) |
Instances
Monad (Controller r) | |
Functor (Controller r) | |
Applicative (Controller r) | |
MonadPeelIO (Controller r) | |
MonadIO (Controller r) |
runController :: Controller r a -> r -> Request -> ResourceT IO (Either Response a)Source
runControllerIO :: Controller r a -> r -> Request -> IO (Either Response a)Source
Run a Controller
in the IO
monad
controllerApp :: r -> Controller r a -> ApplicationSource
Convert the controller into an Application
controllerState :: Controller r rSource
Extract the application-specific state
putState :: r -> Controller r ()Source
request :: Controller r RequestSource
Extract the request
localRequest :: (Request -> Request) -> Controller r a -> Controller r aSource
Modify the request for the given computation
respond :: Response -> Controller r aSource
Provide a response
respond r >>= f === respond r
requestHeader :: HeaderName -> Controller r (Maybe ByteString)Source
Returns the value of the given request header or Nothing
if it is not
present in the HTTP request.
Common Routes
routeHost :: ByteString -> Controller r a -> Controller r ()Source
Matches on the hostname from the Request
. The route only succeeds on
exact matches.
routeTop :: Controller r a -> Controller r ()Source
routeMethod :: StdMethod -> Controller r a -> Controller r ()Source
routeAccept :: ByteString -> Controller r a -> Controller r ()Source
Matches if the request's Content-Type exactly matches the given string
routePattern :: ByteString -> Controller r a -> Controller r ()Source
Routes the given URL pattern. Patterns can include
directories as well as variable patterns (prefixed with :
) to be added
to queryString
(see routeVar
)
- /posts/:id
- /posts/:id/new
- /:date/posts/:category/new
routeName :: ByteString -> Controller r a -> Controller r ()Source
Matches if the first directory in the path matches the given ByteString
routeVar :: ByteString -> Controller r a -> Controller r ()Source
Always matches if there is at least one directory in pathInfo
but and
adds a parameter to queryString
where the key is the first parameter and
the value is the directory consumed from the path.
Inspecting query
The class of types into which query parameters may be converted
Instances
Arguments
:: Parseable a | |
=> ByteString | Parameter name |
-> Controller r (Maybe a) |
queryParam' :: Parseable a => ByteString -> Controller r aSource
Like queryParam
, but throws an exception if the parameter is not present.
queryParams :: Parseable a => ByteString -> Controller r [a]Source
Selects all values with the given parameter name
Arguments
:: Read a | |
=> ByteString | Parameter name |
-> Controller r (Maybe a) |
Like queryParam
, but further processes the parameter value with read
.
If that conversion fails, an exception is thrown.
Arguments
:: Read a | |
=> ByteString | Parameter name |
-> Controller r a |
Like readQueryParam
, but throws an exception if the parameter is not present.
Arguments
:: Read a | |
=> ByteString | Parameter name |
-> Controller r [a] |
Like queryParams
, but further processes the parameter values with read
.
If any read-conversion fails, an exception is thrown.
parseForm :: Controller r ([Param], [(ByteString, FileInfo FilePath)])Source
Parses a HTML form from the request body. It returns a list of Param
s as
well as a list of File
s, which are pairs mapping the name of a file form
field to a FileInfo
pointing to a temporary file with the contents of the
upload.
myController = do (prms, files) <- parseForm let mPicFile = lookup "profile_pic" files case mPicFile of Just (picFile) -> do sourceFile (fileContent picFile) $$ sinkFile ("images/" ++ (fileName picFile)) respond $ redirectTo "/" Nothing -> redirectBack
Redirection via referrer
redirectBack :: Controller r ()Source
Redirect back to the referer. If the referer header is not present
redirect to root (i.e., /
).
Arguments
:: Response | Fallback response |
-> Controller r () |
Redirect back to the referer. If the referer header is not present
fallback on the given Response
.
Exception handling
module Control.Exception.Peel
Integrating other WAI components
class ToApplication r whereSource
The class of types that can be converted to an Application
Methods
toApp :: r -> ApplicationSource
Instances
fromApp :: ToApplication a => a -> Controller r ()Source
Lift an application to a controller
Low-level utilities
body :: Controller r ByteStringSource
Reads and returns the body of the HTTP request.