-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Another Haskell web framework for rapid development -- -- This toolbox provides everything you need to get a quick start into -- web hacking with haskell: routing, middleware, json, blaze, sessions, -- cookies, database helper, csrf-protection, global state @package Spock @version 0.6.5.0 module Web.Spock -- | Run a spock application using the warp server, a given db storageLayer -- and an initial state. Spock works with database libraries that already -- implement connection pooling and with those that don't come with it -- out of the box. For more see the PoolOrConn type. spock :: Int -> SessionCfg sess -> PoolOrConn conn -> st -> SpockM conn sess st () -> IO () -- | Inside the SpockM monad, you may define routes and middleware. type SpockM conn sess st = SpockT (WebStateM conn sess st) -- | The SpockAction is the monad of all route-actions. You have access to -- the database, session and state of your application. type SpockAction conn sess st = ActionT (WebStateM conn sess st) -- | Run a raw spock server on a defined port. If you don't need a custom -- base monad you can just supply id as lift function. spockT :: MonadIO m => Port -> (forall a. m a -> IO a) -> SpockT m () -> IO () data SpockT (m :: * -> *) a data ActionT m a -- | Specify an action that will be run when the HTTP verb GET and -- the given route match get :: MonadIO m => Text -> ActionT m () -> SpockT m () -- | Specify an action that will be run when the HTTP verb POST and -- the given route match post :: MonadIO m => Text -> ActionT m () -> SpockT m () -- | Specify an action that will be run when the HTTP verb HEAD and -- the given route match head :: MonadIO m => Text -> ActionT m () -> SpockT m () -- | Specify an action that will be run when the HTTP verb PUT and -- the given route match put :: MonadIO m => Text -> ActionT m () -> SpockT m () -- | Specify an action that will be run when the HTTP verb DELETE -- and the given route match delete :: MonadIO m => Text -> ActionT m () -> SpockT m () -- | Specify an action that will be run when the HTTP verb PATCH and -- the given route match patch :: MonadIO m => Text -> ActionT m () -> SpockT m () -- | Define a route matching a provided StdMethod and route defRoute :: MonadIO m => StdMethod -> Text -> ActionT m () -> SpockT m () -- | Define a subcomponent -- --
-- subcomponent "/api" $ -- do get "/user" $ text "USER" -- post "/new-user" $ text "OK!" ---- --
-- >>> curl http://localhost:8080/api/user -- USER --subcomponent :: MonadIO m => Text -> SpockT m a -> SpockT m a -- | HTTP standard method (as defined by RFC 2616, and PATCH which is -- defined by RFC 5789). data StdMethod :: * GET :: StdMethod POST :: StdMethod HEAD :: StdMethod PUT :: StdMethod DELETE :: StdMethod TRACE :: StdMethod CONNECT :: StdMethod OPTIONS :: StdMethod PATCH :: StdMethod -- | Combine two routes, ensuring that the slashes don't get messed up combineRoute :: Text -> Text -> Text -- | Get the original Wai Request object request :: MonadIO m => ActionT m Request -- | Read a header header :: MonadIO m => Text -> ActionT m (Maybe Text) -- | Read a cookie cookie :: MonadIO m => Text -> ActionT m (Maybe Text) -- | Get the raw request body body :: MonadIO m => ActionT m ByteString -- | Parse the request body as json jsonBody :: (MonadIO m, FromJSON a) => ActionT m (Maybe a) -- | Parse the request body as json and fails with 500 status code on error jsonBody' :: (MonadIO m, FromJSON a) => ActionT m a -- | Get uploaded files files :: MonadIO m => ActionT m (HashMap Text UploadedFile) data UploadedFile UploadedFile :: Text -> Text -> FilePath -> UploadedFile uf_name :: UploadedFile -> Text uf_contentType :: UploadedFile -> Text uf_tempLocation :: UploadedFile -> FilePath -- | Get all request params params :: MonadIO m => ActionT m [(Text, Text)] -- | Read a request param. Spock looks in route captures first, then in -- POST variables and at last in GET variables param :: (PathPiece p, MonadIO m) => Text -> ActionT m (Maybe p) -- | Like param, but outputs an error when a param is missing param' :: (PathPiece p, MonadIO m) => Text -> ActionT m p -- | Set a response status setStatus :: MonadIO m => Status -> ActionT m () -- | Set a response header. Overwrites already defined headers setHeader :: MonadIO m => Text -> Text -> ActionT m () -- | Redirect to a given url redirect :: MonadIO m => Text -> ActionT m a -- | Abort the current action and jump the next one matching the route jumpNext :: MonadIO m => ActionT m a -- | Set a cookie living for a given number of seconds setCookie :: MonadIO m => Text -> Text -> NominalDiffTime -> ActionT m () -- | Set a cookie living until a specific UTCTime setCookie' :: MonadIO m => Text -> Text -> UTCTime -> ActionT m () -- | Send a ByteString as response body. Provide your own -- Content-Type bytes :: MonadIO m => ByteString -> ActionT m a -- | Send a lazy ByteString as response body. Provide your own -- Content-Type lazyBytes :: MonadIO m => ByteString -> ActionT m a -- | Send text as a response body. Content-Type will be text/plain text :: MonadIO m => Text -> ActionT m a -- | Send a text as response body. Content-Type will be text/plain html :: MonadIO m => Text -> ActionT m a -- | Send a file as response file :: MonadIO m => Text -> FilePath -> ActionT m a -- | Send json as response. Content-Type will be application/json json :: (ToJSON a, MonadIO m) => a -> ActionT m b -- | Send blaze html as response. Content-Type will be text/html blaze :: MonadIO m => Html -> ActionT m a -- | Hook up a Middleware middleware :: MonadIO m => Middleware -> SpockT m () -- | You can feed Spock with either a connection pool, or instructions on -- how to build a connection pool. See ConnBuilder data PoolOrConn a PCPool :: (Pool a) -> PoolOrConn a PCConduitPool :: (Pool a) -> PoolOrConn a PCConn :: (ConnBuilder a) -> PoolOrConn a -- | The ConnBuilder instructs Spock how to create or close a database -- connection. data ConnBuilder a ConnBuilder :: IO a -> (a -> IO ()) -> PoolCfg -> ConnBuilder a cb_createConn :: ConnBuilder a -> IO a cb_destroyConn :: ConnBuilder a -> a -> IO () cb_poolConfiguration :: ConnBuilder a -> PoolCfg -- | If Spock should take care of connection pooling, you need to configure -- it depending on what you need. data PoolCfg PoolCfg :: Int -> Int -> NominalDiffTime -> PoolCfg pc_stripes :: PoolCfg -> Int pc_resPerStripe :: PoolCfg -> Int pc_keepOpenTime :: PoolCfg -> NominalDiffTime class HasSpock m where type family SpockConn m :: * type family SpockState m :: * type family SpockSession m :: * runQuery :: HasSpock m => (SpockConn m -> IO a) -> m a getState :: HasSpock m => m (SpockState m) -- | Configuration for the session manager data SessionCfg a SessionCfg :: Text -> NominalDiffTime -> Int -> a -> SessionCfg a sc_cookieName :: SessionCfg a -> Text sc_sessionTTL :: SessionCfg a -> NominalDiffTime sc_sessionIdEntropy :: SessionCfg a -> Int sc_emptySession :: SessionCfg a -> a -- | Read the stored session readSession :: SpockAction conn sess st sess -- | Write to the current session. Note that all data is stored on the -- server. The user only reciedes a sessionId to be identified. writeSession :: sess -> SpockAction conn sess st () -- | Modify the stored session modifySession :: (sess -> sess) -> SpockAction conn sess st () -- | Globally delete all existing sessions. This is useful for example if -- you want to require all users to relogin clearAllSessions :: SpockAction conn sess st () -- | SafeActions are actions that need to be protected from csrf attacks class (Hashable a, Eq a, Typeable a) => SafeAction conn sess st a runSafeAction :: SafeAction conn sess st a => a -> SpockAction conn sess st () -- | Wire up a safe action: Safe actions are actions that are protected -- from csrf attacks. Here's a usage example: -- --
-- newtype DeleteUser = DeleteUser Int deriving (Hashable, Typeable, Eq) -- -- instance SafeAction Connection () () DeleteUser where -- runSafeAction (DeleteUser i) = -- do runQuery $ deleteUserFromDb i -- redirect "/user-list" -- -- get "/user-details/:userId" $ -- do userId <- param "userId" -- deleteUrl <- safeActionPath (DeleteUser userId) -- html $ TL.concat [ "Click <a href='", TL.fromStrict deleteUrl, "'>here</a> to delete user!" ] ---- -- Note that safeActions currently only support GET and POST requests. safeActionPath :: (SafeAction conn sess st a, HasSpock (SpockAction conn sess st), SpockConn (SpockAction conn sess st) ~ conn, SpockSession (SpockAction conn sess st) ~ sess, SpockState (SpockAction conn sess st) ~ st) => a -> SpockAction conn sess st Text -- | Run a digestive functors form runForm :: (Functor m, MonadIO m) => Text -> Form v (ActionT m) a -> ActionT m (View v, Maybe a) -- | Read the heart of Spock. This is useful if you want to construct your -- own monads that work with runQuery and getState using -- runSpockIO getSpockHeart :: MonadTrans t => t (WebStateM conn sess st) (WebState conn sess st) -- | Run an action inside of Spocks core monad. This allows you to use -- runQuery and getState runSpockIO :: WebState conn sess st -> WebStateM conn sess st a -> IO a data WebStateM conn sess st a data WebState conn sess st