Safe Haskell | Trustworthy |
---|---|
Language | Haskell2010 |
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 ...
Synopsis
- type Controller s = ControllerT s IO
- newtype ControllerT s m a = ControllerT {
- runController :: s -> Request -> m (Either Response a, s)
- controllerApp :: s -> Controller s a -> Application
- controllerState :: Controller s s
- putState :: s -> Controller s ()
- request :: Controller s Request
- localRequest :: (Request -> Request) -> Controller s a -> Controller s a
- respond :: Response -> Controller s a
- requestHeader :: HeaderName -> Controller s (Maybe ByteString)
- routeHost :: ByteString -> Controller s a -> Controller s ()
- routeTop :: Controller s a -> Controller s ()
- routeMethod :: StdMethod -> Controller s a -> Controller s ()
- routeAccept :: ByteString -> Controller s a -> Controller s ()
- routePattern :: Text -> Controller s a -> Controller s ()
- routeName :: Text -> Controller s a -> Controller s ()
- routeVar :: Text -> Controller s a -> Controller s ()
- class Parseable a
- queryParam :: Parseable a => ByteString -> Controller s (Maybe a)
- queryParam' :: Parseable a => ByteString -> Controller s a
- queryParams :: Parseable a => ByteString -> Controller s [a]
- readQueryParam :: Read a => ByteString -> Controller s (Maybe a)
- readQueryParam' :: Read a => ByteString -> Controller s a
- readQueryParams :: Read a => ByteString -> Controller s [a]
- parseForm :: Controller s ([Param], [(ByteString, FileInfo ByteString)])
- redirectBack :: Controller s a
- redirectBackOr :: Response -> Controller s a
- data ControllerException
- body :: Controller s ByteString
- hoistEither :: Either Response a -> Controller s a
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?"
type Controller s = ControllerT s IO Source #
newtype ControllerT s m a Source #
The ControllerT Monad is both a State-like monad which, when run, computes
either a Response
or a result. Within the ControllerT Monad, the remainder
of the computation can be short-circuited by respond
ing with a Response
.
ControllerT | |
|
Instances
controllerApp :: s -> Controller s a -> Application Source #
Convert the controller into an Application
controllerState :: Controller s s Source #
Extract the application-specific state
putState :: s -> Controller s () Source #
request :: Controller s Request Source #
Extract the request
localRequest :: (Request -> Request) -> Controller s a -> Controller s a Source #
Modify the request for the given computation
respond :: Response -> Controller s a Source #
Provide a response
respond r >>= f === respond r
requestHeader :: HeaderName -> Controller s (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 s a -> Controller s () Source #
Matches on the hostname from the Request
. The route only succeeds on
exact matches.
routeTop :: Controller s a -> Controller s () Source #
routeMethod :: StdMethod -> Controller s a -> Controller s () Source #
routeAccept :: ByteString -> Controller s a -> Controller s () Source #
Matches if the request's Content-Type exactly matches the given string
routePattern :: Text -> Controller s a -> Controller s () 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 :: Text -> Controller s a -> Controller s () Source #
Matches if the first directory in the path matches the given ByteString
routeVar :: Text -> Controller s a -> Controller s () 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
Parseable ByteString Source # | |
Defined in Web.Simple.Controller.Trans parse :: ByteString -> ByteString Source # | |
Parseable Text Source # | |
Defined in Web.Simple.Controller.Trans parse :: ByteString -> Text Source # | |
Parseable String Source # | |
Defined in Web.Simple.Controller.Trans parse :: ByteString -> String Source # |
:: Parseable a | |
=> ByteString | Parameter name |
-> Controller s (Maybe a) |
Looks up the parameter name in the request's query string and returns the
Parseable
value or Nothing
.
For example, for a request with query string: "?foo=bar&baz=7",
queryParam "foo"
would return Just "bar"
, but
queryParam "zap"
would return Nothing
.
queryParam' :: Parseable a => ByteString -> Controller s a Source #
Like queryParam
, but throws an exception if the parameter is not present.
queryParams :: Parseable a => ByteString -> Controller s [a] Source #
Selects all values with the given parameter name
:: Read a | |
=> ByteString | Parameter name |
-> Controller s (Maybe a) |
Like queryParam
, but further processes the parameter value with read
.
If that conversion fails, an exception is thrown.
:: Read a | |
=> ByteString | Parameter name |
-> Controller s a |
Like readQueryParam
, but throws an exception if the parameter is not present.
:: Read a | |
=> ByteString | Parameter name |
-> Controller s [a] |
Like queryParams
, but further processes the parameter values with read
.
If any read-conversion fails, an exception is thrown.
parseForm :: Controller s ([Param], [(ByteString, FileInfo ByteString)]) 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.
myControllerT = 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 s a Source #
Redirect back to the referer. If the referer header is not present
redirect to root (i.e., /
).
:: Response | Fallback response |
-> Controller s a |
Redirect back to the referer. If the referer header is not present
fallback on the given Response
.
Exception handling
data ControllerException Source #
Instances
Show ControllerException Source # | |
Defined in Web.Simple.Controller.Trans showsPrec :: Int -> ControllerException -> ShowS # show :: ControllerException -> String # showList :: [ControllerException] -> ShowS # | |
Exception ControllerException Source # | |
Low-level utilities
body :: Controller s ByteString Source #
Reads and returns the body of the HTTP request.
hoistEither :: Either Response a -> Controller s a Source #