-- 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 getting started guide. -- -- Here's a runnable example, with comments, that defines a dummy -- API and implements a webserver that serves this API, using this -- package. @package servant-server @version 0.2.4 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 -- | an even more informative "your json request body wasn't valid" error InvalidBody :: String -> RouteMismatch -- |
--   > mempty = NotFound
--   >
--   > NotFound      mappend             x = x
--   > WrongMethod   mappend InvalidBody s = InvalidBody s
--   > WrongMethod   mappend             _ = WrongMethod
--   > InvalidBody s mappend             _ = InvalidBody s
--   
-- | 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 Server layout :: * where { type family Server layout :: *; } route :: HasServer layout => Proxy layout -> Server layout -> RoutingApplication -- | 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 [Book] -- GET /books
--           :<|> "books" :> ReqBody Book :> Post 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 Book
--   
--   server :: Server MyApi
--   server = getBook
--     where getBook :: Text -> EitherT (Int, String) 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 (Int, String) 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 (Int, String) 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 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 Referer
--   
--   server :: Server MyApi
--   server = viewReferer
--     where viewReferer :: Referer -> EitherT (Int, String) 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 (Int, String) 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 201 along the way. -- | When implementing the handler for a Put endpoint, just like for -- Delete, Get and Post, the handler code runs in -- the EitherT (Int, String) 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 [Book]
--   
--   server :: Server MyApi
--   server = getBooksBy
--     where getBooksBy :: Maybe Text -> EitherT (Int, String) 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 [Book]
--   
--   server :: Server MyApi
--   server = getBooksBy
--     where getBooksBy :: [Text] -> EitherT (Int, String) 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 [Book]
--   
--   server :: Server MyApi
--   server = getBooks
--     where getBooks :: Bool -> EitherT (Int, String) 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 (Int, String) 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 (Int, String) 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 (Int, String) 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. 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 Book :> Post Book
--   
--   server :: Server MyApi
--   server = postBook
--     where postBook :: Book -> EitherT (Int, String) 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. 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.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 (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.Server.Internal.HasServer Servant.API.Delete.Delete instance Data.Aeson.Types.Class.ToJSON result => Servant.Server.Internal.HasServer (Servant.API.Get.Get result) instance (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 Data.Aeson.Types.Class.ToJSON a => Servant.Server.Internal.HasServer (Servant.API.Post.Post a) instance Data.Aeson.Types.Class.ToJSON a => Servant.Server.Internal.HasServer (Servant.API.Put.Put a) instance (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 (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 (GHC.TypeLits.KnownSymbol sym, Servant.Server.Internal.HasServer sublayout) => Servant.Server.Internal.HasServer (Servant.API.QueryParam.QueryFlag sym Servant.API.Sub.:> sublayout) instance (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 (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 (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 (Data.Aeson.Types.Class.FromJSON a, Servant.Server.Internal.HasServer sublayout) => Servant.Server.Internal.HasServer (Servant.API.ReqBody.ReqBody a Servant.API.Sub.:> sublayout) instance (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 [Book] -- GET /books
--           :<|> "books" :> ReqBody Book :> Post 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 class HasServer layout where type Server layout :: * where { type family Server layout :: *; } route :: HasServer layout => Proxy layout -> Server layout -> RoutingApplication -- | This module defines a sever-side handler that lets you serve static -- files. -- -- module Servant.Utils.StaticFiles -- | Serve anything under the specified directory as a Raw endpoint. -- --
--   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 k (t :: k) :: forall k. k -> * Proxy :: Proxy k