| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Servant.Server
Contents
Description
Synopsis
- serve :: HasServer api '[] => Proxy api -> Server api -> Application
- serveWithContext :: HasServer api context => Proxy api -> Context context -> Server api -> Application
- toApplication :: RoutingApplication -> Application
- class HasServer api context where
- type Server api = ServerT api Handler
- data EmptyServer
- emptyServer :: ServerT EmptyAPI m
- newtype Handler a = Handler {
- runHandler' :: ExceptT ServantErr IO a
- runHandler :: Handler a -> IO (Either ServantErr a)
- layout :: HasServer api '[] => Proxy api -> Text
- layoutWithContext :: HasServer api context => Proxy api -> Context context -> Text
- hoistServer :: HasServer api '[] => Proxy api -> (forall x. m x -> n x) -> ServerT api m -> ServerT api n
- tweakResponse :: (RouteResult Response -> RouteResult Response) -> Router env -> Router env
- data Context contextTypes where
- EmptyContext :: Context '[]
- (:.) :: x -> Context xs -> Context (x ': xs)
- class HasContextEntry (context :: [*]) (val :: *) where
- getContextEntry :: Context context -> val
- data NamedContext (name :: Symbol) (subContext :: [*]) = NamedContext (Context subContext)
- descendIntoNamedContext :: forall context name subContext. HasContextEntry context (NamedContext name subContext) => Proxy (name :: Symbol) -> Context context -> Context subContext
- newtype BasicAuthCheck usr = BasicAuthCheck {
- unBasicAuthCheck :: BasicAuthData -> IO (BasicAuthResult usr)
- data BasicAuthResult usr
- = Unauthorized
- | BadPassword
- | NoSuchUser
- | Authorized usr
- data ServantErr = ServantErr {
- errHTTPCode :: Int
- errReasonPhrase :: String
- errBody :: ByteString
- errHeaders :: [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
- err418 :: ServantErr
- err422 :: ServantErr
- err500 :: ServantErr
- err501 :: ServantErr
- err502 :: ServantErr
- err503 :: ServantErr
- err504 :: ServantErr
- err505 :: ServantErr
- type Application = Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
- newtype Tagged (s :: k) b :: forall k. k -> Type -> Type = Tagged {
- unTagged :: b
Run a wai application from an API
serve :: HasServer api '[] => Proxy api -> Server api -> Application #
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 appserveWithContext :: HasServer api context => Proxy api -> Context context -> Server api -> Application #
Construct a wai Application from an API
Handlers for all standard combinators
class HasServer api context where #
Methods
route :: Proxy api -> Context context -> Delayed env (Server api) -> Router env #
hoistServerWithContext :: Proxy api -> Proxy context -> (forall x. m x -> n x) -> ServerT api m -> ServerT api n #
Instances
| HasServer Raw context # | 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 EmptyAPI context # | The server for an type MyApi = "nothing" :> EmptyApi server :: Server MyApi server = emptyAPIServer |
Defined in Servant.Server.Internal | |
| (TypeError (HasServerArrowTypeError a b) :: Constraint) => HasServer (a -> b :: Type) context # | This instance prevents from accidentally using '->' instead of
|
Defined in Servant.Server.Internal | |
| (HasServer a context, HasServer b context) => HasServer (a :<|> b :: Type) context # | 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 = ... |
Defined in Servant.Server.Internal | |
| (HasContextEntry context (NamedContext name subContext), HasServer subApi subContext) => HasServer (WithNamedContext name subContext subApi :: Type) context # | |
Defined in Servant.Server.Internal Associated Types type ServerT (WithNamedContext name subContext subApi) m :: Type # Methods route :: Proxy (WithNamedContext name subContext subApi) -> Context context -> Delayed env (Server (WithNamedContext name subContext subApi)) -> Router env # hoistServerWithContext :: Proxy (WithNamedContext name subContext subApi) -> Proxy context -> (forall x. m x -> n x) -> ServerT (WithNamedContext name subContext subApi) m -> ServerT (WithNamedContext name subContext subApi) n # | |
| (TypeError (HasServerArrowKindError arr) :: Constraint) => HasServer (arr :> api :: Type) context # | This instance catches mistakes when there are non-saturated
type applications on LHS of
|
Defined in Servant.Server.Internal | |
| HasServer api context => HasServer (HttpVersion :> api :: Type) context # | |
Defined in Servant.Server.Internal Associated Types type ServerT (HttpVersion :> api) m :: Type # Methods route :: Proxy (HttpVersion :> api) -> Context context -> Delayed env (Server (HttpVersion :> api)) -> Router env # hoistServerWithContext :: Proxy (HttpVersion :> api) -> Proxy context -> (forall x. m x -> n x) -> ServerT (HttpVersion :> api) m -> ServerT (HttpVersion :> api) n # | |
| (FramingUnrender framing, FromSourceIO chunk a, MimeUnrender ctype chunk, HasServer api context) => HasServer (StreamBody' mods framing ctype a :> api :: Type) context # | |
Defined in Servant.Server.Internal Associated Types type ServerT (StreamBody' mods framing ctype a :> api) m :: Type # Methods route :: Proxy (StreamBody' mods framing ctype a :> api) -> Context context -> Delayed env (Server (StreamBody' mods framing ctype a :> api)) -> Router env # hoistServerWithContext :: Proxy (StreamBody' mods framing ctype a :> api) -> Proxy context -> (forall x. m x -> n x) -> ServerT (StreamBody' mods framing ctype a :> api) m -> ServerT (StreamBody' mods framing ctype a :> api) n # | |
| (AllCTUnrender list a, HasServer api context, SBoolI (FoldLenient mods)) => HasServer (ReqBody' mods list a :> api :: Type) context # | 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 -> Handler Book
postBook book = ...insert into your db... |
Defined in Servant.Server.Internal Methods route :: Proxy (ReqBody' mods list a :> api) -> Context context -> Delayed env (Server (ReqBody' mods list a :> api)) -> Router env # hoistServerWithContext :: Proxy (ReqBody' mods list a :> api) -> Proxy context -> (forall x. m x -> n x) -> ServerT (ReqBody' mods list a :> api) m -> ServerT (ReqBody' mods list a :> api) n # | |
| HasServer api context => HasServer (RemoteHost :> api :: Type) context # | |
Defined in Servant.Server.Internal Associated Types type ServerT (RemoteHost :> api) m :: Type # Methods route :: Proxy (RemoteHost :> api) -> Context context -> Delayed env (Server (RemoteHost :> api)) -> Router env # hoistServerWithContext :: Proxy (RemoteHost :> api) -> Proxy context -> (forall x. m x -> n x) -> ServerT (RemoteHost :> api) m -> ServerT (RemoteHost :> api) n # | |
| (KnownSymbol sym, FromHttpApiData a, HasServer api context, SBoolI (FoldRequired mods), SBoolI (FoldLenient mods)) => HasServer (QueryParam' mods sym a :> api :: Type) context # | 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 -> Handler [Book]
getBooksBy Nothing = ...return all books...
getBooksBy (Just author) = ...return books by the given author... |
Defined in Servant.Server.Internal Associated Types type ServerT (QueryParam' mods sym a :> api) m :: Type # Methods route :: Proxy (QueryParam' mods sym a :> api) -> Context context -> Delayed env (Server (QueryParam' mods sym a :> api)) -> Router env # hoistServerWithContext :: Proxy (QueryParam' mods sym a :> api) -> Proxy context -> (forall x. m x -> n x) -> ServerT (QueryParam' mods sym a :> api) m -> ServerT (QueryParam' mods sym a :> api) n # | |
| (KnownSymbol sym, FromHttpApiData a, HasServer api context) => HasServer (QueryParams sym a :> api :: Type) context # | 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] -> Handler [Book]
getBooksBy authors = ...return all books by these authors... |
Defined in Servant.Server.Internal Associated Types type ServerT (QueryParams sym a :> api) m :: Type # Methods route :: Proxy (QueryParams sym a :> api) -> Context context -> Delayed env (Server (QueryParams sym a :> api)) -> Router env # hoistServerWithContext :: Proxy (QueryParams sym a :> api) -> Proxy context -> (forall x. m x -> n x) -> ServerT (QueryParams sym a :> api) m -> ServerT (QueryParams sym a :> api) n # | |
| (KnownSymbol sym, HasServer api context) => HasServer (QueryFlag sym :> api :: Type) context # | If you use Example: type MyApi = "books" :> QueryFlag "published" :> Get '[JSON] [Book]
server :: Server MyApi
server = getBooks
where getBooks :: Bool -> Handler [Book]
getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument... |
Defined in Servant.Server.Internal | |
| (KnownSymbol sym, FromHttpApiData a, HasServer api context, SBoolI (FoldRequired mods), SBoolI (FoldLenient mods)) => HasServer (Header' mods sym a :> api :: Type) context # | If you use All it asks is for a Example: newtype Referer = Referer Text
deriving (Eq, Show, FromHttpApiData)
-- GET /view-my-referer
type MyApi = "view-my-referer" :> Header "Referer" Referer :> Get '[JSON] Referer
server :: Server MyApi
server = viewReferer
where viewReferer :: Referer -> Handler referer
viewReferer referer = return referer |
Defined in Servant.Server.Internal Methods route :: Proxy (Header' mods sym a :> api) -> Context context -> Delayed env (Server (Header' mods sym a :> api)) -> Router env # hoistServerWithContext :: Proxy (Header' mods sym a :> api) -> Proxy context -> (forall x. m x -> n x) -> ServerT (Header' mods sym a :> api) m -> ServerT (Header' mods sym a :> api) n # | |
| HasServer api context => HasServer (IsSecure :> api :: Type) context # | |
Defined in Servant.Server.Internal | |
| (HasServer api context, HasContextEntry context (AuthHandler Request (AuthServerData (AuthProtect tag)))) => HasServer (AuthProtect tag :> api :: Type) context # | Known orphan instance. |
Defined in Servant.Server.Experimental.Auth Associated Types type ServerT (AuthProtect tag :> api) m :: Type # Methods route :: Proxy (AuthProtect tag :> api) -> Context context -> Delayed env (Server (AuthProtect tag :> api)) -> Router env # hoistServerWithContext :: Proxy (AuthProtect tag :> api) -> Proxy context -> (forall x. m x -> n x) -> ServerT (AuthProtect tag :> api) m -> ServerT (AuthProtect tag :> api) n # | |
| HasServer api ctx => HasServer (Summary desc :> api :: Type) ctx # | Ignore |
Defined in Servant.Server.Internal | |
| HasServer api ctx => HasServer (Description desc :> api :: Type) ctx # | Ignore |
Defined in Servant.Server.Internal Associated Types type ServerT (Description desc :> api) m :: Type # Methods route :: Proxy (Description desc :> api) -> Context ctx -> Delayed env (Server (Description desc :> api)) -> Router env # hoistServerWithContext :: Proxy (Description desc :> api) -> Proxy ctx -> (forall x. m x -> n x) -> ServerT (Description desc :> api) m -> ServerT (Description desc :> api) n # | |
| (KnownSymbol capture, FromHttpApiData a, HasServer api context) => HasServer (Capture' mods capture a :> api :: Type) context # | 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 -> Handler Book
getBook isbn = ... |
Defined in Servant.Server.Internal Methods route :: Proxy (Capture' mods capture a :> api) -> Context context -> Delayed env (Server (Capture' mods capture a :> api)) -> Router env # hoistServerWithContext :: Proxy (Capture' mods capture a :> api) -> Proxy context -> (forall x. m x -> n x) -> ServerT (Capture' mods capture a :> api) m -> ServerT (Capture' mods capture a :> api) n # | |
| (KnownSymbol capture, FromHttpApiData a, HasServer api context) => HasServer (CaptureAll capture a :> api :: Type) context # | If you use You can control how they'll be converted from Example: type MyApi = "src" :> CaptureAll "segments" Text :> Get '[JSON] SourceFile
server :: Server MyApi
server = getSourceFile
where getSourceFile :: [Text] -> Handler Book
getSourceFile pathSegments = ... |
Defined in Servant.Server.Internal Associated Types type ServerT (CaptureAll capture a :> api) m :: Type # Methods route :: Proxy (CaptureAll capture a :> api) -> Context context -> Delayed env (Server (CaptureAll capture a :> api)) -> Router env # hoistServerWithContext :: Proxy (CaptureAll capture a :> api) -> Proxy context -> (forall x. m x -> n x) -> ServerT (CaptureAll capture a :> api) m -> ServerT (CaptureAll capture a :> api) n # | |
| (KnownSymbol realm, HasServer api context, HasContextEntry context (BasicAuthCheck usr)) => HasServer (BasicAuth realm usr :> api :: Type) context # | Basic Authentication |
Defined in Servant.Server.Internal Methods route :: Proxy (BasicAuth realm usr :> api) -> Context context -> Delayed env (Server (BasicAuth realm usr :> api)) -> Router env # hoistServerWithContext :: Proxy (BasicAuth realm usr :> api) -> Proxy context -> (forall x. m x -> n x) -> ServerT (BasicAuth realm usr :> api) m -> ServerT (BasicAuth realm usr :> api) n # | |
| HasServer api context => HasServer (Vault :> api :: Type) context # | |
Defined in Servant.Server.Internal | |
| (KnownSymbol path, HasServer api context) => HasServer (path :> api :: Type) context # | Make sure the incoming request starts with |
Defined in Servant.Server.Internal | |
| (AllCTRender ctypes a, ReflectMethod method, KnownNat status, GetHeaders (Headers h a)) => HasServer (Verb method status ctypes (Headers h a) :: Type) context # | |
Defined in Servant.Server.Internal Methods route :: Proxy (Verb method status ctypes (Headers h a)) -> Context context -> Delayed env (Server (Verb method status ctypes (Headers h a))) -> Router env # hoistServerWithContext :: Proxy (Verb method status ctypes (Headers h a)) -> Proxy context -> (forall x. m x -> n x) -> ServerT (Verb method status ctypes (Headers h a)) m -> ServerT (Verb method status ctypes (Headers h a)) n # | |
| (AllCTRender ctypes a, ReflectMethod method, KnownNat status) => HasServer (Verb method status ctypes a :: Type) context # | |
Defined in Servant.Server.Internal Methods route :: Proxy (Verb method status ctypes a) -> Context context -> Delayed env (Server (Verb method status ctypes a)) -> Router env # hoistServerWithContext :: Proxy (Verb method status ctypes a) -> Proxy context -> (forall x. m x -> n x) -> ServerT (Verb method status ctypes a) m -> ServerT (Verb method status ctypes a) n # | |
| (MimeRender ctype chunk, ReflectMethod method, KnownNat status, FramingRender framing, ToSourceIO chunk a, GetHeaders (Headers h a)) => HasServer (Stream method status framing ctype (Headers h a) :: Type) context # | |
Defined in Servant.Server.Internal Methods route :: Proxy (Stream method status framing ctype (Headers h a)) -> Context context -> Delayed env (Server (Stream method status framing ctype (Headers h a))) -> Router env # hoistServerWithContext :: Proxy (Stream method status framing ctype (Headers h a)) -> Proxy context -> (forall x. m x -> n x) -> ServerT (Stream method status framing ctype (Headers h a)) m -> ServerT (Stream method status framing ctype (Headers h a)) n # | |
| (MimeRender ctype chunk, ReflectMethod method, KnownNat status, FramingRender framing, ToSourceIO chunk a) => HasServer (Stream method status framing ctype a :: Type) context # | |
Defined in Servant.Server.Internal Methods route :: Proxy (Stream method status framing ctype a) -> Context context -> Delayed env (Server (Stream method status framing ctype a)) -> Router env # hoistServerWithContext :: Proxy (Stream method status framing ctype a) -> Proxy context -> (forall x. m x -> n x) -> ServerT (Stream method status framing ctype a) m -> ServerT (Stream method status framing ctype a) n # | |
data EmptyServer #
Singleton type representing a server that serves an empty API.
Instances
| Bounded EmptyServer # | |
Defined in Servant.Server.Internal | |
| Enum EmptyServer # | |
Defined in Servant.Server.Internal Methods succ :: EmptyServer -> EmptyServer # pred :: EmptyServer -> EmptyServer # toEnum :: Int -> EmptyServer # fromEnum :: EmptyServer -> Int # enumFrom :: EmptyServer -> [EmptyServer] # enumFromThen :: EmptyServer -> EmptyServer -> [EmptyServer] # enumFromTo :: EmptyServer -> EmptyServer -> [EmptyServer] # enumFromThenTo :: EmptyServer -> EmptyServer -> EmptyServer -> [EmptyServer] # | |
| Eq EmptyServer # | |
Defined in Servant.Server.Internal | |
| Show EmptyServer # | |
Defined in Servant.Server.Internal Methods showsPrec :: Int -> EmptyServer -> ShowS # show :: EmptyServer -> String # showList :: [EmptyServer] -> ShowS # | |
emptyServer :: ServerT EmptyAPI m #
Server for EmptyAPI
Constructors
| Handler | |
Fields
| |
Instances
| Monad Handler # | |
| Functor Handler # | |
| Applicative Handler # | |
| MonadIO Handler # | |
Defined in Servant.Server.Internal.Handler | |
| MonadThrow Handler # | |
Defined in Servant.Server.Internal.Handler | |
| MonadCatch Handler # | |
| MonadMask Handler # | |
Defined in Servant.Server.Internal.Handler | |
| MonadBase IO Handler # | |
Defined in Servant.Server.Internal.Handler | |
| MonadBaseControl IO Handler # | |
| MonadError ServantErr Handler # | |
Defined in Servant.Server.Internal.Handler Methods throwError :: ServantErr -> Handler a # catchError :: Handler a -> (ServantErr -> Handler a) -> Handler a # | |
| Generic (Handler a) # | |
| type StM Handler a # | |
Defined in Servant.Server.Internal.Handler | |
| type Rep (Handler a) # | |
Defined in Servant.Server.Internal.Handler type Rep (Handler a) = D1 (MetaData "Handler" "Servant.Server.Internal.Handler" "servant-server-0.15-HF1uH8kQibOBU6OIbdPD0I" True) (C1 (MetaCons "Handler" PrefixI True) (S1 (MetaSel (Just "runHandler'") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (ExceptT ServantErr IO a)))) | |
runHandler :: Handler a -> IO (Either ServantErr a) #
Debugging the server layout
layout :: HasServer api '[] => Proxy api -> Text #
The function layout produces a textual description of the internal
router layout for debugging purposes. Note that the router layout is
determined just by the API, not by the handlers.
Example:
For the following API
type API =
"a" :> "d" :> Get '[JSON] NoContent
:<|> "b" :> Capture "x" Int :> Get '[JSON] Bool
:<|> "c" :> Put '[JSON] Bool
:<|> "a" :> "e" :> Get '[JSON] Int
:<|> "b" :> Capture "x" Int :> Put '[JSON] Bool
:<|> Rawwe get the following output:
/ ├─ a/ │ ├─ d/ │ │ └─• │ └─ e/ │ └─• ├─ b/ │ └─ <capture>/ │ ├─• │ ┆ │ └─• ├─ c/ │ └─• ┆ └─ <raw>
Explanation of symbols:
├- Normal lines reflect static branching via a table.
a/- Nodes reflect static path components.
─•- Leaves reflect endpoints.
<capture>/- This is a delayed capture of a path component.
<raw>- This is a part of the API we do not know anything about.
┆- Dashed lines suggest a dynamic choice between the part above and below. If there is a success for fatal failure in the first part, that one takes precedence. If both parts fail, the "better" error code will be returned.
Enter / hoisting server
hoistServer :: HasServer api '[] => Proxy api -> (forall x. m x -> n x) -> ServerT api m -> ServerT api n #
Hoist server implementation.
Sometimes our cherished Handler monad isn't quite the type you'd like for
your handlers. Maybe you want to thread some configuration in a Reader
monad. Or have your types ensure that your handlers don't do any IO. Use
hoistServer (a successor of now deprecated enter).
With hoistServer, you can provide a function,
to convert any number of endpoints from one type constructor to
another. For example
Note: Server Raw can also be entered. It will be retagged.
>>>import Control.Monad.Reader>>>type ReaderAPI = "ep1" :> Get '[JSON] Int :<|> "ep2" :> Get '[JSON] String :<|> Raw :<|> EmptyAPI>>>let readerApi = Proxy :: Proxy ReaderAPI>>>let readerServer = return 1797 :<|> ask :<|> Tagged (error "raw server") :<|> emptyServer :: ServerT ReaderAPI (Reader String)>>>let nt x = return (runReader x "hi")>>>let mainServer = hoistServer readerApi nt readerServer :: Server ReaderAPI
Functions based on mmorph
tweakResponse :: (RouteResult Response -> RouteResult Response) -> Router env -> Router env #
Apply a transformation to the response of a Router.
Context
data Context contextTypes where #
Contexts are used to pass values to combinators. (They are not meant
to be used to pass parameters to your handlers, i.e. they should not replace
any custom ReaderT-monad-stack that you're using
with hoistServer.) If you don't use combinators that
require any context entries, you can just use serve as always.
If you are using combinators that require a non-empty Context you have to
use serveWithContext and pass it a Context that contains all
the values your combinators need. A Context is essentially a heterogenous
list and accessing the elements is being done by type (see getContextEntry).
The parameter of the type Context is a type-level list reflecting the types
of the contained context entries. To create a Context with entries, use the
operator (::.)
>>>:type True :. () :. EmptyContextTrue :. () :. EmptyContext :: Context '[Bool, ()]
Constructors
| EmptyContext :: Context '[] | |
| (:.) :: x -> Context xs -> Context (x ': xs) infixr 5 |
class HasContextEntry (context :: [*]) (val :: *) where #
This class is used to access context entries in Contexts. getContextEntry
returns the first value where the type matches:
>>>getContextEntry (True :. False :. EmptyContext) :: BoolTrue
If the Context does not contain an entry of the requested type, you'll get
an error:
>>>getContextEntry (True :. False :. EmptyContext) :: String... ...No instance for (HasContextEntry '[] [Char]) ...
Methods
getContextEntry :: Context context -> val #
Instances
| HasContextEntry (val ': xs) val # | |
Defined in Servant.Server.Internal.Context Methods getContextEntry :: Context (val ': xs) -> val # | |
| HasContextEntry xs val => HasContextEntry (notIt ': xs) val # | |
Defined in Servant.Server.Internal.Context Methods getContextEntry :: Context (notIt ': xs) -> val # | |
NamedContext
data NamedContext (name :: Symbol) (subContext :: [*]) #
Normally context entries are accessed by their types. In case you need
to have multiple values of the same type in your Context and need to access
them, we provide NamedContext. You can think of it as sub-namespaces for
Contexts.
Constructors
| NamedContext (Context subContext) |
descendIntoNamedContext :: forall context name subContext. HasContextEntry context (NamedContext name subContext) => Proxy (name :: Symbol) -> Context context -> Context subContext #
descendIntoNamedContext allows you to access NamedContexts. Usually you
won't have to use it yourself but instead use a combinator like
WithNamedContext.
This is how descendIntoNamedContext works:
>>>:set -XFlexibleContexts>>>let subContext = True :. EmptyContext>>>:type subContextsubContext :: Context '[Bool]>>>let parentContext = False :. (NamedContext subContext :: NamedContext "subContext" '[Bool]) :. EmptyContext>>>:type parentContextparentContext :: Context '[Bool, NamedContext "subContext" '[Bool]]>>>descendIntoNamedContext (Proxy :: Proxy "subContext") parentContext :: Context '[Bool]True :. EmptyContext
Basic Authentication
newtype BasicAuthCheck usr #
Datatype wrapping a function used to check authentication.
Constructors
| BasicAuthCheck | |
Fields
| |
Instances
| Functor BasicAuthCheck # | |
Defined in Servant.Server.Internal.BasicAuth Methods fmap :: (a -> b) -> BasicAuthCheck a -> BasicAuthCheck b # (<$) :: a -> BasicAuthCheck b -> BasicAuthCheck a # | |
| Generic (BasicAuthCheck usr) # | |
Defined in Servant.Server.Internal.BasicAuth Associated Types type Rep (BasicAuthCheck usr) :: Type -> Type # Methods from :: BasicAuthCheck usr -> Rep (BasicAuthCheck usr) x # to :: Rep (BasicAuthCheck usr) x -> BasicAuthCheck usr # | |
| type Rep (BasicAuthCheck usr) # | |
Defined in Servant.Server.Internal.BasicAuth type Rep (BasicAuthCheck usr) = D1 (MetaData "BasicAuthCheck" "Servant.Server.Internal.BasicAuth" "servant-server-0.15-HF1uH8kQibOBU6OIbdPD0I" True) (C1 (MetaCons "BasicAuthCheck" PrefixI True) (S1 (MetaSel (Just "unBasicAuthCheck") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (BasicAuthData -> IO (BasicAuthResult usr))))) | |
data BasicAuthResult usr #
servant-server's current implementation of basic authentication is not immune to certian kinds of timing attacks. Decoding payloads does not take a fixed amount of time.
The result of authentication/authorization
Constructors
| Unauthorized | |
| BadPassword | |
| NoSuchUser | |
| Authorized usr |
Instances
General Authentication
Default error type
data ServantErr #
Constructors
| ServantErr | |
Fields
| |
Instances
| Eq ServantErr # | |
Defined in Servant.Server.Internal.ServantErr | |
| Read ServantErr # | |
Defined in Servant.Server.Internal.ServantErr Methods readsPrec :: Int -> ReadS ServantErr # readList :: ReadS [ServantErr] # readPrec :: ReadPrec ServantErr # readListPrec :: ReadPrec [ServantErr] # | |
| Show ServantErr # | |
Defined in Servant.Server.Internal.ServantErr Methods showsPrec :: Int -> ServantErr -> ShowS # show :: ServantErr -> String # showList :: [ServantErr] -> ShowS # | |
| Exception ServantErr # | |
Defined in Servant.Server.Internal.ServantErr Methods toException :: ServantErr -> SomeException # fromException :: SomeException -> Maybe ServantErr # displayException :: ServantErr -> String # | |
| MonadError ServantErr Handler # | |
Defined in Servant.Server.Internal.Handler Methods throwError :: ServantErr -> Handler a # catchError :: Handler a -> (ServantErr -> Handler a) -> Handler a # | |
3XX
err300 :: ServantErr #
err300 Multiple Choices
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err300 { errBody = "I can't choose." }err301 :: ServantErr #
err302 :: ServantErr #
err303 :: ServantErr #
err304 :: ServantErr #
err305 :: ServantErr #
err307 :: ServantErr #
4XX
err400 :: ServantErr #
err400 Bad Request
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err400 { errBody = "Your request makes no sense to me." }err401 :: ServantErr #
err401 Unauthorized
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err401 { errBody = "Your credentials are invalid." }err402 :: ServantErr #
err402 Payment Required
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err402 { errBody = "You have 0 credits. Please give me $$$." }err403 :: ServantErr #
err403 Forbidden
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err403 { errBody = "Please login first." }err404 :: ServantErr #
err404 Not Found
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err404 { errBody = "(╯°□°)╯︵ ┻━┻)." }err405 :: ServantErr #
err405 Method Not Allowed
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err405 { errBody = "Your account privileges does not allow for this. Please pay $$$." }err406 :: ServantErr #
err407 :: ServantErr #
err407 Proxy Authentication Required
Example:
failingHandler :: Handler () failingHandler = throwError err407
err409 :: ServantErr #
err409 Conflict
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err409 { errBody = "Transaction conflicts with 59879cb56c7c159231eeacdd503d755f7e835f74" }err410 :: ServantErr #
err410 Gone
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err410 { errBody = "I know it was here at some point, but.. I blame bad luck." }err411 :: ServantErr #
err412 :: ServantErr #
err412 Precondition Failed
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err412 { errBody = "Precondition fail: x < 42 && y > 57" }err413 :: ServantErr #
err413 Request Entity Too Large
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err413 { errBody = "Request exceeded 64k." }err414 :: ServantErr #
err414 Request-URI Too Large
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err414 { errBody = "Maximum length is 64." }err415 :: ServantErr #
err415 Unsupported Media Type
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err415 { errBody = "Supported media types: gif, png" }err416 :: ServantErr #
err416 Request range not satisfiable
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err416 { errBody = "Valid range is [0, 424242]." }err417 :: ServantErr #
err417 Expectation Failed
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err417 { errBody = "I found a quux in the request. This isn't going to work." }err418 :: ServantErr #
err418 Expectation Failed
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err418 { errBody = "Apologies, this is not a webserver but a teapot." }err422 :: ServantErr #
err422 Unprocessable Entity
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err422 { errBody = "I understood your request, but can't process it." }5XX
err500 :: ServantErr #
err500 Internal Server Error
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err500 { errBody = "Exception in module A.B.C:55. Have a great day!" }err501 :: ServantErr #
err501 Not Implemented
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err501 { errBody = "/v1/foo is not supported with quux in the request." }err502 :: ServantErr #
err502 Bad Gateway
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err502 { errBody = "Tried gateway foo, bar, and baz. None responded." }err503 :: ServantErr #
err503 Service Unavailable
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err503 { errBody = "We're rewriting in PHP." }err504 :: ServantErr #
err504 Gateway Time-out
Example:
failingHandler :: Handler ()
failingHandler = throwError $ err504 { errBody = "Backend foobar did not respond in 5 seconds." }err505 :: ServantErr #
err505 HTTP Version not supported
Example usage:
failingHandler :: Handler ()
failingHandler = throwError $ err505 { errBody = "I support HTTP/4.0 only." }Re-exports
type Application = Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived #
The WAI application.
Note that, since WAI 3.0, this type is structured in continuation passing
style to allow for proper safe resource handling. This was handled in the
past via other means (e.g., ResourceT). As a demonstration:
app :: Application
app req respond = bracket_
(putStrLn "Allocating scarce resource")
(putStrLn "Cleaning up")
(respond $ responseLBS status200 [] "Hello World")
newtype Tagged (s :: k) b :: forall k. k -> Type -> Type #
A value is a value Tagged s bb with an attached phantom type s.
This can be used in place of the more traditional but less safe idiom of
passing in an undefined value with the type, because unlike an (s -> b),
a can't try to use the argument Tagged s bs as a real value.
Moreover, you don't have to rely on the compiler to inline away the extra argument, because the newtype is "free"
Tagged has kind k -> * -> * if the compiler supports PolyKinds, therefore
there is an extra k showing in the instance haddocks that may cause confusion.
Instances
| Bitraversable (Tagged :: Type -> Type -> Type) | |
Defined in Data.Tagged Methods bitraverse :: Applicative f => (a -> f c) -> (b -> f d) -> Tagged a b -> f (Tagged c d) # | |
| Bifoldable (Tagged :: Type -> Type -> Type) | |
| Bifunctor (Tagged :: Type -> Type -> Type) | |
| Eq2 (Tagged :: Type -> Type -> Type) | |
| Ord2 (Tagged :: Type -> Type -> Type) | |
Defined in Data.Tagged | |
| Read2 (Tagged :: Type -> Type -> Type) | |
Defined in Data.Tagged Methods liftReadsPrec2 :: (Int -> ReadS a) -> ReadS [a] -> (Int -> ReadS b) -> ReadS [b] -> Int -> ReadS (Tagged a b) # liftReadList2 :: (Int -> ReadS a) -> ReadS [a] -> (Int -> ReadS b) -> ReadS [b] -> ReadS [Tagged a b] # liftReadPrec2 :: ReadPrec a -> ReadPrec [a] -> ReadPrec b -> ReadPrec [b] -> ReadPrec (Tagged a b) # liftReadListPrec2 :: ReadPrec a -> ReadPrec [a] -> ReadPrec b -> ReadPrec [b] -> ReadPrec [Tagged a b] # | |
| Show2 (Tagged :: Type -> Type -> Type) | |
| Generic1 (Tagged s :: Type -> Type) | |
| Monad (Tagged s) | |
| Functor (Tagged s) | |
| Applicative (Tagged s) | |
| Foldable (Tagged s) | |
Defined in Data.Tagged Methods fold :: Monoid m => Tagged s m -> m # foldMap :: Monoid m => (a -> m) -> Tagged s a -> m # foldr :: (a -> b -> b) -> b -> Tagged s a -> b # foldr' :: (a -> b -> b) -> b -> Tagged s a -> b # foldl :: (b -> a -> b) -> b -> Tagged s a -> b # foldl' :: (b -> a -> b) -> b -> Tagged s a -> b # foldr1 :: (a -> a -> a) -> Tagged s a -> a # foldl1 :: (a -> a -> a) -> Tagged s a -> a # elem :: Eq a => a -> Tagged s a -> Bool # maximum :: Ord a => Tagged s a -> a # minimum :: Ord a => Tagged s a -> a # | |
| Traversable (Tagged s) | |
| Eq1 (Tagged s) | |
| Ord1 (Tagged s) | |
Defined in Data.Tagged | |
| Read1 (Tagged s) | |
Defined in Data.Tagged | |
| Show1 (Tagged s) | |
| Bounded b => Bounded (Tagged s b) | |
| Enum a => Enum (Tagged s a) | |
Defined in Data.Tagged Methods succ :: Tagged s a -> Tagged s a # pred :: Tagged s a -> Tagged s a # fromEnum :: Tagged s a -> Int # enumFrom :: Tagged s a -> [Tagged s a] # enumFromThen :: Tagged s a -> Tagged s a -> [Tagged s a] # enumFromTo :: Tagged s a -> Tagged s a -> [Tagged s a] # enumFromThenTo :: Tagged s a -> Tagged s a -> Tagged s a -> [Tagged s a] # | |
| Eq b => Eq (Tagged s b) | |
| Floating a => Floating (Tagged s a) | |
Defined in Data.Tagged Methods exp :: Tagged s a -> Tagged s a # log :: Tagged s a -> Tagged s a # sqrt :: Tagged s a -> Tagged s a # (**) :: Tagged s a -> Tagged s a -> Tagged s a # logBase :: Tagged s a -> Tagged s a -> Tagged s a # sin :: Tagged s a -> Tagged s a # cos :: Tagged s a -> Tagged s a # tan :: Tagged s a -> Tagged s a # asin :: Tagged s a -> Tagged s a # acos :: Tagged s a -> Tagged s a # atan :: Tagged s a -> Tagged s a # sinh :: Tagged s a -> Tagged s a # cosh :: Tagged s a -> Tagged s a # tanh :: Tagged s a -> Tagged s a # asinh :: Tagged s a -> Tagged s a # acosh :: Tagged s a -> Tagged s a # atanh :: Tagged s a -> Tagged s a # log1p :: Tagged s a -> Tagged s a # expm1 :: Tagged s a -> Tagged s a # | |
| Fractional a => Fractional (Tagged s a) | |
| Integral a => Integral (Tagged s a) | |
Defined in Data.Tagged Methods quot :: Tagged s a -> Tagged s a -> Tagged s a # rem :: Tagged s a -> Tagged s a -> Tagged s a # div :: Tagged s a -> Tagged s a -> Tagged s a # mod :: Tagged s a -> Tagged s a -> Tagged s a # quotRem :: Tagged s a -> Tagged s a -> (Tagged s a, Tagged s a) # divMod :: Tagged s a -> Tagged s a -> (Tagged s a, Tagged s a) # | |
| (Data s, Data b) => Data (Tagged s b) | |
Defined in Data.Tagged Methods gfoldl :: (forall d b0. Data d => c (d -> b0) -> d -> c b0) -> (forall g. g -> c g) -> Tagged s b -> c (Tagged s b) # gunfold :: (forall b0 r. Data b0 => c (b0 -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Tagged s b) # toConstr :: Tagged s b -> Constr # dataTypeOf :: Tagged s b -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Tagged s b)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Tagged s b)) # gmapT :: (forall b0. Data b0 => b0 -> b0) -> Tagged s b -> Tagged s b # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Tagged s b -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Tagged s b -> r # gmapQ :: (forall d. Data d => d -> u) -> Tagged s b -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Tagged s b -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Tagged s b -> m (Tagged s b) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Tagged s b -> m (Tagged s b) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Tagged s b -> m (Tagged s b) # | |
| Num a => Num (Tagged s a) | |
Defined in Data.Tagged | |
| Ord b => Ord (Tagged s b) | |
| Read b => Read (Tagged s b) | |
| Real a => Real (Tagged s a) | |
Defined in Data.Tagged Methods toRational :: Tagged s a -> Rational # | |
| RealFloat a => RealFloat (Tagged s a) | |
Defined in Data.Tagged Methods floatRadix :: Tagged s a -> Integer # floatDigits :: Tagged s a -> Int # floatRange :: Tagged s a -> (Int, Int) # decodeFloat :: Tagged s a -> (Integer, Int) # encodeFloat :: Integer -> Int -> Tagged s a # exponent :: Tagged s a -> Int # significand :: Tagged s a -> Tagged s a # scaleFloat :: Int -> Tagged s a -> Tagged s a # isInfinite :: Tagged s a -> Bool # isDenormalized :: Tagged s a -> Bool # isNegativeZero :: Tagged s a -> Bool # | |
| RealFrac a => RealFrac (Tagged s a) | |
| Show b => Show (Tagged s b) | |
| Ix b => Ix (Tagged s b) | |
Defined in Data.Tagged Methods range :: (Tagged s b, Tagged s b) -> [Tagged s b] # index :: (Tagged s b, Tagged s b) -> Tagged s b -> Int # unsafeIndex :: (Tagged s b, Tagged s b) -> Tagged s b -> Int inRange :: (Tagged s b, Tagged s b) -> Tagged s b -> Bool # rangeSize :: (Tagged s b, Tagged s b) -> Int # unsafeRangeSize :: (Tagged s b, Tagged s b) -> Int | |
| IsString a => IsString (Tagged s a) | |
Defined in Data.Tagged Methods fromString :: String -> Tagged s a # | |
| Generic (Tagged s b) | |
| Semigroup a => Semigroup (Tagged s a) | |
| (Semigroup a, Monoid a) => Monoid (Tagged s a) | |
| Storable a => Storable (Tagged s a) | |
Defined in Data.Tagged Methods alignment :: Tagged s a -> Int # peekElemOff :: Ptr (Tagged s a) -> Int -> IO (Tagged s a) # pokeElemOff :: Ptr (Tagged s a) -> Int -> Tagged s a -> IO () # peekByteOff :: Ptr b -> Int -> IO (Tagged s a) # pokeByteOff :: Ptr b -> Int -> Tagged s a -> IO () # | |
| Bits a => Bits (Tagged s a) | |
Defined in Data.Tagged Methods (.&.) :: Tagged s a -> Tagged s a -> Tagged s a # (.|.) :: Tagged s a -> Tagged s a -> Tagged s a # xor :: Tagged s a -> Tagged s a -> Tagged s a # complement :: Tagged s a -> Tagged s a # shift :: Tagged s a -> Int -> Tagged s a # rotate :: Tagged s a -> Int -> Tagged s a # setBit :: Tagged s a -> Int -> Tagged s a # clearBit :: Tagged s a -> Int -> Tagged s a # complementBit :: Tagged s a -> Int -> Tagged s a # testBit :: Tagged s a -> Int -> Bool # bitSizeMaybe :: Tagged s a -> Maybe Int # bitSize :: Tagged s a -> Int # isSigned :: Tagged s a -> Bool # shiftL :: Tagged s a -> Int -> Tagged s a # unsafeShiftL :: Tagged s a -> Int -> Tagged s a # shiftR :: Tagged s a -> Int -> Tagged s a # unsafeShiftR :: Tagged s a -> Int -> Tagged s a # rotateL :: Tagged s a -> Int -> Tagged s a # | |
| FiniteBits a => FiniteBits (Tagged s a) | |
Defined in Data.Tagged Methods finiteBitSize :: Tagged s a -> Int # countLeadingZeros :: Tagged s a -> Int # countTrailingZeros :: Tagged s a -> Int # | |
| NFData b => NFData (Tagged s b) | |
Defined in Data.Tagged | |
| ToFormKey a => ToFormKey (Tagged b a) | |
Defined in Web.Internal.FormUrlEncoded | |
| FromFormKey a => FromFormKey (Tagged b a) | |
Defined in Web.Internal.FormUrlEncoded | |
| ToHttpApiData a => ToHttpApiData (Tagged b a) | |
Defined in Web.Internal.HttpApiData Methods toUrlPiece :: Tagged b a -> Text # toEncodedUrlPiece :: Tagged b a -> Builder # toHeader :: Tagged b a -> ByteString # toQueryParam :: Tagged b a -> Text # | |
| FromHttpApiData a => FromHttpApiData (Tagged b a) | |
Defined in Web.Internal.HttpApiData Methods parseUrlPiece :: Text -> Either Text (Tagged b a) # parseHeader :: ByteString -> Either Text (Tagged b a) # | |
| type Rep1 (Tagged s :: Type -> Type) | |
Defined in Data.Tagged | |
| type Rep (Tagged s b) | |
Defined in Data.Tagged | |