Safe Haskell | None |
---|---|
Language | Haskell2010 |
- data ReqBodyState
- = Uncalled
- | Called !ByteString
- | Done !ByteString
- toApplication :: RoutingApplication -> Application
- data RouteMismatch
- newtype RouteResult a = RR {}
- failWith :: RouteMismatch -> RouteResult a
- succeedWith :: a -> RouteResult a
- isMismatch :: RouteResult a -> Bool
- pathIsEmpty :: Request -> Bool
- type RoutingApplication = Request -> (RouteResult Response -> IO ResponseReceived) -> IO ResponseReceived
- splitMatrixParameters :: Text -> (Text, Text)
- parsePathInfo :: Request -> [Text]
- processedPathInfo :: Request -> [Text]
- class HasServer layout where
- type ServerT layout m :: *
- route :: Proxy layout -> Server layout -> RoutingApplication
- type Server layout = ServerT layout (EitherT ServantErr IO)
- captured :: FromText a => proxy (Capture sym a) -> Text -> Maybe a
- parseMatrixText :: ByteString -> QueryText
- ct_wildcard :: ByteString
Documentation
Route mismatch
data RouteMismatch Source
NotFound | the usual "not found" error |
WrongMethod | a more informative "you just got the HTTP method wrong" error |
UnsupportedMediaType | request body has unsupported media type |
InvalidBody String | an even more informative "your json request body wasn't valid" error |
HttpError Status (Maybe ByteString) | an even even more informative arbitrary HTTP response code error. |
newtype RouteResult a Source
A wrapper around
.Either
RouteMismatch
a
Eq a => Eq (RouteResult a) | |
Show a => Show (RouteResult a) | |
Monoid (RouteResult a) | If we get a This in particular means that if we could get several |
failWith :: RouteMismatch -> RouteResult a Source
succeedWith :: a -> RouteResult a Source
isMismatch :: RouteResult a -> Bool Source
pathIsEmpty :: Request -> Bool Source
Like `null . pathInfo`, but works with redundant trailing slashes.
type RoutingApplication Source
= Request | the request, the field |
-> (RouteResult Response -> IO ResponseReceived) | |
-> IO ResponseReceived |
splitMatrixParameters :: Text -> (Text, Text) Source
parsePathInfo :: Request -> [Text] Source
processedPathInfo :: Request -> [Text] Source
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.
class HasServer layout where Source
route :: Proxy layout -> Server layout -> RoutingApplication Source
HasServer * Raw | 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" |
(HasServer * a, HasServer * b) => HasServer * ((:<|>) a b) | A server for 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 = ... |
(GetHeaders (Headers h v), AllCTRender ctypes v) => HasServer * (Get ctypes (Headers h v)) | |
HasServer * (Get ctypes ()) | |
AllCTRender ctypes a => HasServer * (Get ctypes a) | When implementing the handler for a If successfully returning a value, we use the type-level list, combined
with the request's |
(GetHeaders (Headers h v), AllCTRender ctypes v) => HasServer * (Post ctypes (Headers h v)) | |
HasServer * (Post ctypes ()) | |
AllCTRender ctypes a => HasServer * (Post ctypes a) | When implementing the handler for a If successfully returning a value, we use the type-level list, combined
with the request's |
(GetHeaders (Headers h v), AllCTRender ctypes v) => HasServer * (Delete ctypes (Headers h v)) | |
HasServer * (Delete ctypes ()) | |
AllCTRender ctypes a => HasServer * (Delete ctypes a) | If you have a The code of the handler will, just like
for |
(GetHeaders (Headers h v), AllCTRender ctypes v) => HasServer * (Put ctypes (Headers h v)) | |
HasServer * (Put ctypes ()) | |
AllCTRender ctypes a => HasServer * (Put ctypes a) | When implementing the handler for a If successfully returning a value, we use the type-level list, combined
with the request's |
(GetHeaders (Headers h v), AllCTRender ctypes v) => HasServer * (Patch ctypes (Headers h v)) | |
HasServer * (Patch ctypes ()) | |
AllCTRender ctypes a => HasServer * (Patch ctypes a) | When implementing the handler for a If successfully returning a value, we just require that its type has
a |
(AllCTUnrender list a, HasServer k sublayout) => HasServer * ((:>) * k (ReqBody * list a) sublayout) | If you use All it asks is for a Example: type MyApi = "books" :> ReqBody '[JSON] Book :> Post '[JSON] Book server :: Server MyApi server = postBook where postBook :: Book -> EitherT (Int, String) IO Book postBook book = ...insert into your db... |
(KnownSymbol sym, HasServer k sublayout) => HasServer * ((:>) * k (MatrixFlag sym) sublayout) | If you use 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... |
(KnownSymbol sym, FromText a, HasServer k sublayout) => HasServer * ((:>) * k (MatrixParams * sym a) sublayout) | If you use This lets servant worry about looking up 0 or more values in the query string
associated to You can control how the individual values are converted from 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... |
(KnownSymbol sym, FromText a, HasServer k sublayout) => HasServer * ((:>) * k (MatrixParam * sym a) sublayout) | If you use 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 You can control how it'll be converted from 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... |
(KnownSymbol sym, HasServer k sublayout) => HasServer * ((:>) * k (QueryFlag sym) sublayout) | If you use Example: type MyApi = "books" :> QueryFlag "published" :> Get '[JSON] [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... |
(KnownSymbol sym, FromText a, HasServer k sublayout) => HasServer * ((:>) * k (QueryParams * sym a) sublayout) | If you use This lets servant worry about looking up 0 or more values in the query string
associated to You can control how the individual values are converted from Example: type MyApi = "books" :> QueryParams "authors" Text :> Get '[JSON] [Book] server :: Server MyApi server = getBooksBy where getBooksBy :: [Text] -> EitherT (Int, String) IO [Book] getBooksBy authors = ...return all books by these authors... |
(KnownSymbol sym, FromText a, HasServer k sublayout) => HasServer * ((:>) * k (QueryParam * sym a) sublayout) | If you use 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 You can control how it'll be converted from Example: type MyApi = "books" :> QueryParam "author" Text :> Get '[JSON] [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... |
(KnownSymbol sym, FromText a, HasServer k sublayout) => HasServer * ((:>) * k (Header sym a) sublayout) | If you use All it asks is for a 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 (Int, String) IO referer viewReferer referer = return referer |
(KnownSymbol capture, FromText a, HasServer k sublayout) => HasServer * ((:>) * k (Capture * capture a) sublayout) | If you use You can control how it'll be converted from Example: type MyApi = "books" :> Capture "isbn" Text :> Get '[JSON] Book server :: Server MyApi server = getBook where getBook :: Text -> EitherT (Int, String) IO Book getBook isbn = ... |
(KnownSymbol path, HasServer k sublayout) => HasServer * ((:>) Symbol k path sublayout) | Make sure the incoming request starts with |