-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A family of combinators for defining webservices APIs and serving them -- @package servant-server @version 0.4.2 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 Show ServantErr instance Eq 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 Typeable (:~>) instance Enter (m a) (m :~> n) (n a) instance Category (:~>) instance Enter b arg ret => Enter (a -> b) arg (a -> ret) instance (Enter typ1 arg1 ret1, Enter typ2 arg2 ret2, arg1 ~ arg2) => Enter (typ1 :<|> typ2) arg1 (ret1 :<|> ret2) 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 -> (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 [overlap ok] Eq RouteMismatch instance [overlap ok] Ord RouteMismatch instance [overlap ok] Show RouteMismatch instance [overlap ok] Eq a => Eq (RouteResult a) instance [overlap ok] Show a => Show (RouteResult a) instance [overlap ok] (KnownSymbol path, HasServer sublayout) => HasServer (path :> sublayout) instance [overlap ok] (AllCTUnrender list a, HasServer sublayout) => HasServer (ReqBody list a :> sublayout) instance [overlap ok] HasServer Raw instance [overlap ok] (KnownSymbol sym, HasServer sublayout) => HasServer (MatrixFlag sym :> sublayout) instance [overlap ok] (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (MatrixParams sym a :> sublayout) instance [overlap ok] (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (MatrixParam sym a :> sublayout) instance [overlap ok] (KnownSymbol sym, HasServer sublayout) => HasServer (QueryFlag sym :> sublayout) instance [overlap ok] (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (QueryParams sym a :> sublayout) instance [overlap ok] (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (QueryParam sym a :> sublayout) instance [overlap ok] (GetHeaders (Headers h v), AllCTRender ctypes v) => HasServer (Patch ctypes (Headers h v)) instance [overlap ok] HasServer (Patch ctypes ()) instance [overlap ok] AllCTRender ctypes a => HasServer (Patch ctypes a) instance [overlap ok] (GetHeaders (Headers h v), AllCTRender ctypes v) => HasServer (Put ctypes (Headers h v)) instance [overlap ok] HasServer (Put ctypes ()) instance [overlap ok] AllCTRender ctypes a => HasServer (Put ctypes a) instance [overlap ok] (GetHeaders (Headers h v), AllCTRender ctypes v) => HasServer (Post ctypes (Headers h v)) instance [overlap ok] HasServer (Post ctypes ()) instance [overlap ok] AllCTRender ctypes a => HasServer (Post ctypes a) instance [overlap ok] (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (Header sym a :> sublayout) instance [overlap ok] (GetHeaders (Headers h v), AllCTRender ctypes v) => HasServer (Get ctypes (Headers h v)) instance [overlap ok] HasServer (Get ctypes ()) instance [overlap ok] AllCTRender ctypes a => HasServer (Get ctypes a) instance [overlap ok] (GetHeaders (Headers h v), AllCTRender ctypes v) => HasServer (Delete ctypes (Headers h v)) instance [overlap ok] HasServer (Delete ctypes ()) instance [overlap ok] AllCTRender ctypes a => HasServer (Delete ctypes a) instance [overlap ok] (KnownSymbol capture, FromText a, HasServer sublayout) => HasServer (Capture capture a :> sublayout) instance [overlap ok] (HasServer a, HasServer b) => HasServer (a :<|> b) instance [overlap ok] Monoid (RouteResult a) instance [overlap ok] Monoid RouteMismatch -- | 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