-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A family of combinators for defining webservices APIs and serving them -- -- A family of combinators for defining webservices APIs and serving them -- -- You can learn about the basics in the tutorial. -- -- Here is a runnable example, with comments, that defines a dummy -- API and implements a webserver that serves this API, using this -- package. -- -- CHANGELOG @package servant-server @version 0.4.4.4 module Servant.Server.Internal.ServantErr data ServantErr ServantErr :: Int -> String -> ByteString -> [Header] -> ServantErr [errHTTPCode] :: ServantErr -> Int [errReasonPhrase] :: ServantErr -> String [errBody] :: ServantErr -> ByteString [errHeaders] :: ServantErr -> [Header] responseServantErr :: ServantErr -> Response err300 :: ServantErr err301 :: ServantErr err302 :: ServantErr err303 :: ServantErr err304 :: ServantErr err305 :: ServantErr err307 :: ServantErr err400 :: ServantErr err401 :: ServantErr err402 :: ServantErr err403 :: ServantErr err404 :: ServantErr err405 :: ServantErr err406 :: ServantErr err407 :: ServantErr err409 :: ServantErr err410 :: ServantErr err411 :: ServantErr err412 :: ServantErr err413 :: ServantErr err414 :: ServantErr err415 :: ServantErr err416 :: ServantErr err417 :: ServantErr err500 :: ServantErr err501 :: ServantErr err502 :: ServantErr err503 :: ServantErr err504 :: ServantErr err505 :: ServantErr instance GHC.Classes.Eq Servant.Server.Internal.ServantErr.ServantErr instance GHC.Show.Show Servant.Server.Internal.ServantErr.ServantErr module Servant.Server.Internal.Enter class Enter typ arg ret | typ arg -> ret, typ ret -> arg enter :: Enter typ arg ret => arg -> typ -> ret -- | A natural transformation from m to n. Used to -- enter particular datatypes. newtype (:~>) m n Nat :: (forall a. m a -> n a) -> (:~>) m n [unNat] :: (:~>) m n -> forall a. m a -> n a -- | Like lift. liftNat :: (MonadTrans t, Monad m) => m :~> t m runReaderTNat :: r -> (ReaderT r m :~> m) evalStateTLNat :: Monad m => s -> (StateT s m :~> m) evalStateTSNat :: Monad m => s -> (StateT s m :~> m) -- | Log the contents of WriterT with the function provided as the -- first argument, and return the value of the WriterT -- computation logWriterTSNat :: MonadIO m => (w -> IO ()) -> (WriterT w m :~> m) -- | Like logWriterTSNat, but for strict WriterT. logWriterTLNat :: MonadIO m => (w -> IO ()) -> (WriterT w m :~> m) fromExceptT :: ExceptT e m :~> EitherT e m -- | Like mmorph's hoist. hoistNat :: (MFunctor t, Monad m) => (m :~> n) -> (t m :~> t n) -- | Like mmorph's embed. embedNat :: (MMonad t, Monad n) => (m :~> t n) -> (t m :~> t n) -- | Like mmorph's squash. squashNat :: (Monad m, MMonad t) => t (t m) :~> t m -- | Like mmorph's generalize. generalizeNat :: Applicative m => Identity :~> m instance (Servant.Server.Internal.Enter.Enter typ1 arg1 ret1, Servant.Server.Internal.Enter.Enter typ2 arg2 ret2, arg1 ~ arg2) => Servant.Server.Internal.Enter.Enter (typ1 Servant.API.Alternative.:<|> typ2) arg1 (ret1 Servant.API.Alternative.:<|> ret2) instance Servant.Server.Internal.Enter.Enter b arg ret => Servant.Server.Internal.Enter.Enter (a -> b) arg (a -> ret) instance Control.Category.Category (Servant.Server.Internal.Enter.:~>) instance Servant.Server.Internal.Enter.Enter (m a) (m Servant.Server.Internal.Enter.:~> n) (n a) module Servant.Server.Internal data ReqBodyState Uncalled :: ReqBodyState Called :: !ByteString -> ReqBodyState Done :: !ByteString -> ReqBodyState toApplication :: RoutingApplication -> Application data RouteMismatch -- | the usual "not found" error NotFound :: RouteMismatch -- | a more informative "you just got the HTTP method wrong" error WrongMethod :: RouteMismatch -- | request body has unsupported media type UnsupportedMediaType :: RouteMismatch -- | an even more informative "your json request body wasn't valid" error InvalidBody :: String -> RouteMismatch -- | an even even more informative arbitrary HTTP response code error. HttpError :: Status -> (Maybe ByteString) -> RouteMismatch -- | A wrapper around Either RouteMismatch a. newtype RouteResult a RR :: Either RouteMismatch a -> RouteResult a [routeResult] :: RouteResult a -> Either RouteMismatch a failWith :: RouteMismatch -> RouteResult a succeedWith :: a -> RouteResult a isMismatch :: RouteResult a -> Bool -- | Like `null . pathInfo`, but works with redundant trailing slashes. pathIsEmpty :: Request -> Bool -- | If we get a Right, it has precedence over everything else. -- -- This in particular means that if we could get several Rights, -- only the first we encounter would be taken into account. type RoutingApplication = Request the request, the field 'pathInfo' may be modified by url routing -> (RouteResult Response -> IO ResponseReceived) -> IO ResponseReceived splitMatrixParameters :: Text -> (Text, Text) parsePathInfo :: Request -> [Text] -- | Returns a processed pathInfo from the request. -- -- In order to handle matrix parameters in the request correctly, the raw -- pathInfo needs to be processed, so routing works as intended. Therefor -- this function should be used to access the pathInfo for routing -- purposes. processedPathInfo :: Request -> [Text] class HasServer layout where type family ServerT layout (m :: * -> *) :: * route :: HasServer layout => Proxy layout -> Server layout -> RoutingApplication type Server layout = ServerT layout (EitherT ServantErr IO) -- | A server for a :<|> b first tries to match the -- request against the route represented by a and if it fails -- tries b. You must provide a request handler for each route. -- --
-- type MyApi = "books" :> Get '[JSON] [Book] -- GET /books -- :<|> "books" :> ReqBody Book :> Post '[JSON] Book -- POST /books -- -- server :: Server MyApi -- server = listAllBooks :<|> postBook -- where listAllBooks = ... -- postBook book = ... --captured :: FromText a => proxy (Capture sym a) -> Text -> Maybe a -- | If you use Capture in one of the endpoints for your API, this -- automatically requires your server-side handler to be a function that -- takes an argument of the type specified by the Capture. This -- lets servant worry about getting it from the URL and turning it into a -- value of the type you specify. -- -- You can control how it'll be converted from Text to your type -- by simply providing an instance of FromText for your type. -- -- Example: -- --
-- type MyApi = "books" :> Capture "isbn" Text :> Get '[JSON] Book -- -- server :: Server MyApi -- server = getBook -- where getBook :: Text -> EitherT ServantErr IO Book -- getBook isbn = ... ---- | If you have a Delete endpoint in your API, the handler for this -- endpoint is meant to delete a resource. -- -- The code of the handler will, just like for Get, Post -- and Put, run in EitherT ServantErr IO (). The -- Int represents the status code and the String a message -- to be returned. You can use left to painlessly error out if the -- conditions for a successful deletion are not met. -- | When implementing the handler for a Get endpoint, just like for -- Delete, Post and Put, the handler code runs in -- the EitherT ServantErr IO monad, where the Int -- represents the status code and the String a message, returned -- in case of failure. You can quite handily use left to quickly -- fail if some conditions are not met. -- -- If successfully returning a value, we use the type-level list, -- combined with the request's Accept header, to encode the -- value for you (returning a status code of 200). If there was no -- Accept header or it was */*, we return encode using -- the first Content-Type type on the list. -- | If you use Header in one of the endpoints for your API, this -- automatically requires your server-side handler to be a function that -- takes an argument of the type specified by Header. This lets -- servant worry about extracting it from the request and turning it into -- a value of the type you specify. -- -- All it asks is for a FromText instance. -- -- Example: -- --
-- newtype Referer = Referer Text -- deriving (Eq, Show, FromText, ToText) -- -- -- GET /view-my-referer -- type MyApi = "view-my-referer" :> Header "Referer" Referer :> Get '[JSON] Referer -- -- server :: Server MyApi -- server = viewReferer -- where viewReferer :: Referer -> EitherT ServantErr IO referer -- viewReferer referer = return referer ---- | When implementing the handler for a Post endpoint, just like -- for Delete, Get and Put, the handler code runs in -- the EitherT ServantErr IO monad, where the Int -- represents the status code and the String a message, returned -- in case of failure. You can quite handily use left to quickly -- fail if some conditions are not met. -- -- If successfully returning a value, we use the type-level list, -- combined with the request's Accept header, to encode the -- value for you (returning a status code of 201). If there was no -- Accept header or it was */*, we return encode using -- the first Content-Type type on the list. -- | When implementing the handler for a Put endpoint, just like for -- Delete, Get and Post, the handler code runs in -- the EitherT ServantErr IO monad, where the Int -- represents the status code and the String a message, returned -- in case of failure. You can quite handily use left to quickly -- fail if some conditions are not met. -- -- If successfully returning a value, we use the type-level list, -- combined with the request's Accept header, to encode the -- value for you (returning a status code of 200). If there was no -- Accept header or it was */*, we return encode using -- the first Content-Type type on the list. -- | When implementing the handler for a Patch endpoint, just like -- for Delete, Get and Put, the handler code runs in -- the EitherT ServantErr IO monad, where the Int -- represents the status code and the String a message, returned -- in case of failure. You can quite handily use left to quickly -- fail if some conditions are not met. -- -- If successfully returning a value, we just require that its type has a -- ToJSON instance and servant takes care of encoding it for -- you, yielding status code 200 along the way. -- | If you use QueryParam "author" Text in one of the -- endpoints for your API, this automatically requires your server-side -- handler to be a function that takes an argument of type -- Maybe Text. -- -- This lets servant worry about looking it up in the query string and -- turning it into a value of the type you specify, enclosed in -- Maybe, because it may not be there and servant would then hand -- you Nothing. -- -- You can control how it'll be converted from Text to your type -- by simply providing an instance of FromText for your type. -- -- Example: -- --
-- type MyApi = "books" :> QueryParam "author" Text :> Get '[JSON] [Book] -- -- server :: Server MyApi -- server = getBooksBy -- where getBooksBy :: Maybe Text -> EitherT ServantErr IO [Book] -- getBooksBy Nothing = ...return all books... -- getBooksBy (Just author) = ...return books by the given author... ---- | If you use QueryParams "authors" Text in one of the -- endpoints for your API, this automatically requires your server-side -- handler to be a function that takes an argument of type -- [Text]. -- -- This lets servant worry about looking up 0 or more values in the query -- string associated to authors and turning each of them into a -- value of the type you specify. -- -- You can control how the individual values are converted from -- Text to your type by simply providing an instance of -- FromText for your type. -- -- Example: -- --
-- type MyApi = "books" :> QueryParams "authors" Text :> Get '[JSON] [Book] -- -- server :: Server MyApi -- server = getBooksBy -- where getBooksBy :: [Text] -> EitherT ServantErr IO [Book] -- getBooksBy authors = ...return all books by these authors... ---- | If you use QueryFlag "published" in one of the -- endpoints for your API, this automatically requires your server-side -- handler to be a function that takes an argument of type Bool. -- -- Example: -- --
-- type MyApi = "books" :> QueryFlag "published" :> Get '[JSON] [Book] -- -- server :: Server MyApi -- server = getBooks -- where getBooks :: Bool -> EitherT ServantErr IO [Book] -- getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument... --parseMatrixText :: ByteString -> QueryText -- | If you use MatrixParam "author" Text in one of the -- endpoints for your API, this automatically requires your server-side -- handler to be a function that takes an argument of type -- Maybe Text. -- -- This lets servant worry about looking it up in the query string and -- turning it into a value of the type you specify, enclosed in -- Maybe, because it may not be there and servant would then hand -- you Nothing. -- -- You can control how it'll be converted from Text to your type -- by simply providing an instance of FromText for your type. -- -- Example: -- --
-- type MyApi = "books" :> MatrixParam "author" Text :> Get [Book] -- -- server :: Server MyApi -- server = getBooksBy -- where getBooksBy :: Maybe Text -> EitherT ServantErr IO [Book] -- getBooksBy Nothing = ...return all books... -- getBooksBy (Just author) = ...return books by the given author... ---- | If you use MatrixParams "authors" Text in one of the -- endpoints for your API, this automatically requires your server-side -- handler to be a function that takes an argument of type -- [Text]. -- -- This lets servant worry about looking up 0 or more values in the query -- string associated to authors and turning each of them into a -- value of the type you specify. -- -- You can control how the individual values are converted from -- Text to your type by simply providing an instance of -- FromText for your type. -- -- Example: -- --
-- type MyApi = "books" :> MatrixParams "authors" Text :> Get [Book] -- -- server :: Server MyApi -- server = getBooksBy -- where getBooksBy :: [Text] -> EitherT ServantErr IO [Book] -- getBooksBy authors = ...return all books by these authors... ---- | If you use MatrixFlag "published" in one of the -- endpoints for your API, this automatically requires your server-side -- handler to be a function that takes an argument of type Bool. -- -- Example: -- --
-- type MyApi = "books" :> MatrixFlag "published" :> Get [Book] -- -- server :: Server MyApi -- server = getBooks -- where getBooks :: Bool -> EitherT ServantErr IO [Book] -- getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument... ---- | Just pass the request to the underlying application and serve its -- response. -- -- Example: -- --
-- type MyApi = "images" :> Raw -- -- server :: Server MyApi -- server = serveDirectory "/var/www/images" ---- | If you use ReqBody in one of the endpoints for your API, this -- automatically requires your server-side handler to be a function that -- takes an argument of the type specified by ReqBody. The -- Content-Type header is inspected, and the list provided is -- used to attempt deserialization. If the request does not have a -- Content-Type header, it is treated as -- application/octet-stream. This lets servant worry about -- extracting it from the request and turning it into a value of the type -- you specify. -- -- All it asks is for a FromJSON instance. -- -- Example: -- --
-- type MyApi = "books" :> ReqBody '[JSON] Book :> Post '[JSON] Book -- -- server :: Server MyApi -- server = postBook -- where postBook :: Book -> EitherT ServantErr IO Book -- postBook book = ...insert into your db... ---- | Make sure the incoming request starts with "/path", strip it -- and pass the rest of the request path to sublayout. ct_wildcard :: ByteString instance GHC.Show.Show a => GHC.Show.Show (Servant.Server.Internal.RouteResult a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Servant.Server.Internal.RouteResult a) instance GHC.Show.Show Servant.Server.Internal.RouteMismatch instance GHC.Classes.Ord Servant.Server.Internal.RouteMismatch instance GHC.Classes.Eq Servant.Server.Internal.RouteMismatch instance GHC.Base.Monoid Servant.Server.Internal.RouteMismatch instance GHC.Base.Monoid (Servant.Server.Internal.RouteResult a) instance (Servant.Server.Internal.HasServer a, Servant.Server.Internal.HasServer b) => Servant.Server.Internal.HasServer (a Servant.API.Alternative.:<|> b) instance forall (k :: BOX) (capture :: GHC.TypeLits.Symbol) a (sublayout :: k). (GHC.TypeLits.KnownSymbol capture, Servant.Common.Text.FromText a, Servant.Server.Internal.HasServer sublayout) => Servant.Server.Internal.HasServer (Servant.API.Capture.Capture capture a Servant.API.Sub.:> sublayout) instance Servant.API.ContentTypes.AllCTRender ctypes a => Servant.Server.Internal.HasServer (Servant.API.Delete.Delete ctypes a) instance Servant.Server.Internal.HasServer (Servant.API.Delete.Delete ctypes ()) instance (Servant.API.ResponseHeaders.GetHeaders (Servant.API.ResponseHeaders.Headers h v), Servant.API.ContentTypes.AllCTRender ctypes v) => Servant.Server.Internal.HasServer (Servant.API.Delete.Delete ctypes (Servant.API.ResponseHeaders.Headers h v)) instance Servant.API.ContentTypes.AllCTRender ctypes a => Servant.Server.Internal.HasServer (Servant.API.Get.Get ctypes a) instance Servant.Server.Internal.HasServer (Servant.API.Get.Get ctypes ()) instance (Servant.API.ResponseHeaders.GetHeaders (Servant.API.ResponseHeaders.Headers h v), Servant.API.ContentTypes.AllCTRender ctypes v) => Servant.Server.Internal.HasServer (Servant.API.Get.Get ctypes (Servant.API.ResponseHeaders.Headers h v)) instance forall (k :: BOX) (sym :: GHC.TypeLits.Symbol) a (sublayout :: k). (GHC.TypeLits.KnownSymbol sym, Servant.Common.Text.FromText a, Servant.Server.Internal.HasServer sublayout) => Servant.Server.Internal.HasServer (Servant.API.Header.Header sym a Servant.API.Sub.:> sublayout) instance Servant.API.ContentTypes.AllCTRender ctypes a => Servant.Server.Internal.HasServer (Servant.API.Post.Post ctypes a) instance Servant.Server.Internal.HasServer (Servant.API.Post.Post ctypes ()) instance (Servant.API.ResponseHeaders.GetHeaders (Servant.API.ResponseHeaders.Headers h v), Servant.API.ContentTypes.AllCTRender ctypes v) => Servant.Server.Internal.HasServer (Servant.API.Post.Post ctypes (Servant.API.ResponseHeaders.Headers h v)) instance Servant.API.ContentTypes.AllCTRender ctypes a => Servant.Server.Internal.HasServer (Servant.API.Put.Put ctypes a) instance Servant.Server.Internal.HasServer (Servant.API.Put.Put ctypes ()) instance (Servant.API.ResponseHeaders.GetHeaders (Servant.API.ResponseHeaders.Headers h v), Servant.API.ContentTypes.AllCTRender ctypes v) => Servant.Server.Internal.HasServer (Servant.API.Put.Put ctypes (Servant.API.ResponseHeaders.Headers h v)) instance Servant.API.ContentTypes.AllCTRender ctypes a => Servant.Server.Internal.HasServer (Servant.API.Patch.Patch ctypes a) instance Servant.Server.Internal.HasServer (Servant.API.Patch.Patch ctypes ()) instance (Servant.API.ResponseHeaders.GetHeaders (Servant.API.ResponseHeaders.Headers h v), Servant.API.ContentTypes.AllCTRender ctypes v) => Servant.Server.Internal.HasServer (Servant.API.Patch.Patch ctypes (Servant.API.ResponseHeaders.Headers h v)) instance forall (k :: BOX) (sym :: GHC.TypeLits.Symbol) a (sublayout :: k). (GHC.TypeLits.KnownSymbol sym, Servant.Common.Text.FromText a, Servant.Server.Internal.HasServer sublayout) => Servant.Server.Internal.HasServer (Servant.API.QueryParam.QueryParam sym a Servant.API.Sub.:> sublayout) instance forall (k :: BOX) (sym :: GHC.TypeLits.Symbol) a (sublayout :: k). (GHC.TypeLits.KnownSymbol sym, Servant.Common.Text.FromText a, Servant.Server.Internal.HasServer sublayout) => Servant.Server.Internal.HasServer (Servant.API.QueryParam.QueryParams sym a Servant.API.Sub.:> sublayout) instance forall (k :: BOX) (sym :: GHC.TypeLits.Symbol) (sublayout :: k). (GHC.TypeLits.KnownSymbol sym, Servant.Server.Internal.HasServer sublayout) => Servant.Server.Internal.HasServer (Servant.API.QueryParam.QueryFlag sym Servant.API.Sub.:> sublayout) instance forall (k :: BOX) (sym :: GHC.TypeLits.Symbol) a (sublayout :: k). (GHC.TypeLits.KnownSymbol sym, Servant.Common.Text.FromText a, Servant.Server.Internal.HasServer sublayout) => Servant.Server.Internal.HasServer (Servant.API.MatrixParam.MatrixParam sym a Servant.API.Sub.:> sublayout) instance forall (k :: BOX) (sym :: GHC.TypeLits.Symbol) a (sublayout :: k). (GHC.TypeLits.KnownSymbol sym, Servant.Common.Text.FromText a, Servant.Server.Internal.HasServer sublayout) => Servant.Server.Internal.HasServer (Servant.API.MatrixParam.MatrixParams sym a Servant.API.Sub.:> sublayout) instance forall (k :: BOX) (sym :: GHC.TypeLits.Symbol) (sublayout :: k). (GHC.TypeLits.KnownSymbol sym, Servant.Server.Internal.HasServer sublayout) => Servant.Server.Internal.HasServer (Servant.API.MatrixParam.MatrixFlag sym Servant.API.Sub.:> sublayout) instance Servant.Server.Internal.HasServer Servant.API.Raw.Raw instance forall (k :: BOX) (list :: [*]) a (sublayout :: k). (Servant.API.ContentTypes.AllCTUnrender list a, Servant.Server.Internal.HasServer sublayout) => Servant.Server.Internal.HasServer (Servant.API.ReqBody.ReqBody list a Servant.API.Sub.:> sublayout) instance forall (k :: BOX) (path :: GHC.TypeLits.Symbol) (sublayout :: k). (GHC.TypeLits.KnownSymbol path, Servant.Server.Internal.HasServer sublayout) => Servant.Server.Internal.HasServer (path Servant.API.Sub.:> sublayout) -- | This module lets you implement Servers for defined APIs. You'll -- most likely just need serve. module Servant.Server -- | serve allows you to implement an API and produce a wai -- Application. -- -- Example: -- --
-- type MyApi = "books" :> Get '[JSON] [Book] -- GET /books -- :<|> "books" :> ReqBody Book :> Post '[JSON] Book -- POST /books -- -- server :: Server MyApi -- server = listAllBooks :<|> postBook -- where listAllBooks = ... -- postBook book = ... -- -- myApi :: Proxy MyApi -- myApi = Proxy -- -- app :: Application -- app = serve myApi server -- -- main :: IO () -- main = Network.Wai.Handler.Warp.run 8080 app --serve :: HasServer layout => Proxy layout -> Server layout -> Application toApplication :: RoutingApplication -> Application class HasServer layout where type family ServerT layout (m :: * -> *) :: * route :: HasServer layout => Proxy layout -> Server layout -> RoutingApplication type Server layout = ServerT layout (EitherT ServantErr IO) enter :: Enter typ arg ret => arg -> typ -> ret -- | A natural transformation from m to n. Used to -- enter particular datatypes. newtype (:~>) m n Nat :: (forall a. m a -> n a) -> (:~>) m n [unNat] :: (:~>) m n -> forall a. m a -> n a -- | Like lift. liftNat :: (MonadTrans t, Monad m) => m :~> t m runReaderTNat :: r -> (ReaderT r m :~> m) evalStateTLNat :: Monad m => s -> (StateT s m :~> m) evalStateTSNat :: Monad m => s -> (StateT s m :~> m) -- | Like logWriterTSNat, but for strict WriterT. logWriterTLNat :: MonadIO m => (w -> IO ()) -> (WriterT w m :~> m) -- | Log the contents of WriterT with the function provided as the -- first argument, and return the value of the WriterT -- computation logWriterTSNat :: MonadIO m => (w -> IO ()) -> (WriterT w m :~> m) fromExceptT :: ExceptT e m :~> EitherT e m -- | Like mmorph's hoist. hoistNat :: (MFunctor t, Monad m) => (m :~> n) -> (t m :~> t n) -- | Like mmorph's embed. embedNat :: (MMonad t, Monad n) => (m :~> t n) -> (t m :~> t n) -- | Like mmorph's squash. squashNat :: (Monad m, MMonad t) => t (t m) :~> t m -- | Like mmorph's generalize. generalizeNat :: Applicative m => Identity :~> m data ServantErr ServantErr :: Int -> String -> ByteString -> [Header] -> ServantErr [errHTTPCode] :: ServantErr -> Int [errReasonPhrase] :: ServantErr -> String [errBody] :: ServantErr -> ByteString [errHeaders] :: ServantErr -> [Header] err300 :: ServantErr err301 :: ServantErr err302 :: ServantErr err303 :: ServantErr err304 :: ServantErr err305 :: ServantErr err307 :: ServantErr err400 :: ServantErr err401 :: ServantErr err402 :: ServantErr err403 :: ServantErr err404 :: ServantErr err405 :: ServantErr err406 :: ServantErr err407 :: ServantErr err409 :: ServantErr err410 :: ServantErr err411 :: ServantErr err412 :: ServantErr err413 :: ServantErr err414 :: ServantErr err415 :: ServantErr err416 :: ServantErr err417 :: ServantErr err500 :: ServantErr err501 :: ServantErr err502 :: ServantErr err503 :: ServantErr err504 :: ServantErr err505 :: ServantErr -- | This module defines a sever-side handler that lets you serve static -- files. -- --
-- type MyApi = "static" :> Raw -- -- server :: Server MyApi -- server = serveDirectory "/var/www" ---- -- would capture any request to /static/<something> and -- look for <something> under /var/www. -- -- It will do its best to guess the MIME type for that file, based on the -- extension, and send an appropriate Content-Type header if -- possible. -- -- If your goal is to serve HTML, CSS and Javascript files that use the -- rest of the API as a webapp backend, you will most likely not want the -- static files to be hidden behind a /static/ prefix. In that -- case, remember to put the serveDirectory handler in the last -- position, because servant will try to match the handlers in -- order. serveDirectory :: FilePath -> Server Raw module Servant -- | A concrete, poly-kinded proxy type data Proxy (t :: k) :: k -> * Proxy :: Proxy