Safe Haskell | None |
---|---|
Language | Haskell2010 |
Extends Servant with context, based on RIO. The context should be a tuple of all your moudles and configs and stuff, so that the Data.Has module would let you access these items by type.
Synopsis
- asProxyTypeOf :: a -> proxy a -> a
- data Proxy (t :: k) :: forall k. k -> * = Proxy
- data KProxy t = KProxy
- type family If (cond :: Bool) (tru :: k) (fls :: k) :: k where ...
- class ToHttpApiData a where
- class FromHttpApiData a where
- data URI = URI {}
- data HttpVersion = HttpVersion {}
- data StdMethod
- throwError :: MonadError e m => e -> m a
- allFieldLinks' :: (HasLink (ToServantApi routes), GenericServant routes (AsLink a), ToServant routes (AsLink a) ~ MkLink (ToServantApi routes) a) => (Link -> a) -> routes (AsLink a)
- allFieldLinks :: (HasLink (ToServantApi routes), GenericServant routes (AsLink Link), ToServant routes (AsLink Link) ~ MkLink (ToServantApi routes) Link) => routes (AsLink Link)
- fieldLink' :: (IsElem endpoint (ToServantApi routes), HasLink endpoint, GenericServant routes AsApi) => (Link -> a) -> (routes AsApi -> endpoint) -> MkLink endpoint a
- fieldLink :: (IsElem endpoint (ToServantApi routes), HasLink endpoint, GenericServant routes AsApi) => (routes AsApi -> endpoint) -> MkLink endpoint Link
- allLinks' :: HasLink api => (Link -> a) -> Proxy api -> MkLink api a
- allLinks :: HasLink api => Proxy api -> MkLink api Link
- safeLink' :: (IsElem endpoint api, HasLink endpoint) => (Link -> a) -> Proxy api -> Proxy endpoint -> MkLink endpoint a
- safeLink :: (IsElem endpoint api, HasLink endpoint) => Proxy api -> Proxy endpoint -> MkLink endpoint Link
- linkURI' :: LinkArrayElementStyle -> Link -> URI
- linkURI :: Link -> URI
- linkQueryParams :: Link -> [Param]
- linkSegments :: Link -> [String]
- data Link
- data Param
- data LinkArrayElementStyle
- data AsLink a
- class HasLink (endpoint :: k) where
- data WithNamedContext (name :: Symbol) (subContext :: [*]) subApi
- type family Endpoints api :: [*] where ...
- type family IsElem' a s :: Constraint
- type family IsElem endpoint api :: Constraint where ...
- type family IsSubAPI sub api :: Constraint where ...
- type family AllIsElem (xs :: [*]) api :: Constraint where ...
- type family IsIn endpoint api :: Constraint where ...
- type family IsStrictSubAPI sub api :: Constraint where ...
- type family AllIsIn (xs :: [*]) api :: Constraint where ...
- type family MapSub (e :: k) (xs :: [*]) :: [*] where ...
- type family AppendList (xs :: [a]) (ys :: [a]) :: [a] where ...
- type family IsSubList (a :: [t]) (b :: [t]) :: Constraint where ...
- type Elem (e :: t) (es :: [t]) = ElemGo e es es
- type family ElemGo (e :: t) (es :: [t]) (orig :: t1) :: Constraint where ...
- type family Or a b :: Constraint where ...
- data Verb (method :: k1) (statusCode :: Nat) (contentTypes :: [*]) a :: forall k1. k1 -> Nat -> [*] -> * -> *
- type Get = Verb GET 200
- type Post = Verb POST 200
- type Put = Verb PUT 200
- type Delete = Verb DELETE 200
- type Patch = Verb PATCH 200
- type PostCreated = Verb POST 201
- type GetAccepted = Verb GET 202
- type PostAccepted = Verb POST 202
- type DeleteAccepted = Verb DELETE 202
- type PatchAccepted = Verb PATCH 202
- type PutAccepted = Verb PUT 202
- type GetNonAuthoritative = Verb GET 203
- type PostNonAuthoritative = Verb POST 203
- type DeleteNonAuthoritative = Verb DELETE 203
- type PatchNonAuthoritative = Verb PATCH 203
- type PutNonAuthoritative = Verb PUT 203
- type GetNoContent = Verb GET 204
- type PostNoContent = Verb POST 204
- type DeleteNoContent = Verb DELETE 204
- type PatchNoContent = Verb PATCH 204
- type PutNoContent = Verb PUT 204
- type GetResetContent = Verb GET 205
- type PostResetContent = Verb POST 205
- type GetPartialContent = Verb GET 206
- class ReflectMethod (a :: k) where
- data (path :: k) :> a :: forall k. k -> * -> *
- data Stream (method :: k1) (status :: Nat) framing contentType a :: forall k1. k1 -> Nat -> * -> * -> * -> *
- type StreamGet = Stream GET 200
- type StreamPost = Stream POST 200
- newtype StreamGenerator a = StreamGenerator {
- getStreamGenerator :: (a -> IO ()) -> (a -> IO ()) -> IO ()
- class ToStreamGenerator a b | a -> b where
- newtype ResultStream a = ResultStream (forall b. (IO (Maybe (Either String a)) -> IO b) -> IO b)
- class BuildFromStream a b where
- class FramingRender (strategy :: k) (a :: k1) where
- data BoundaryStrategy
- data ByteStringParser a = ByteStringParser {
- parseIncremental :: ByteString -> Maybe (a, ByteString)
- parseEOF :: ByteString -> (a, ByteString)
- class FramingUnrender (strategy :: k) (a :: k1) where
- data NoFraming
- data NewlineFraming
- data NetstringFraming
- noHeader :: AddHeader h v orig new => orig -> new
- addHeader :: AddHeader h v orig new => v -> orig -> new
- data Headers (ls :: [*]) a = Headers {
- getResponse :: a
- getHeadersHList :: HList ls
- data ResponseHeader (sym :: Symbol) a
- data HList (a :: [*]) where
- class BuildHeadersTo (hs :: [*]) where
- class GetHeaders ls where
- class AddHeader (h :: Symbol) v orig new | h v orig -> new, new -> h, new -> v, new -> orig
- type ReqBody = ReqBody' (Required ': (Strict ': ([] :: [*])))
- data ReqBody' (mods :: [*]) (contentTypes :: [*]) a
- data RemoteHost
- data Raw
- type QueryParam = QueryParam' (Optional ': (Strict ': ([] :: [*])))
- data QueryParam' (mods :: [*]) (sym :: Symbol) a
- data QueryParams (sym :: Symbol) a
- data QueryFlag (sym :: Symbol)
- type Header = (Header' (Optional ': (Strict ': ([] :: [*]))) :: Symbol -> k -> *)
- data Header' (mods :: [*]) (sym :: Symbol) (a :: k) :: forall k. [*] -> Symbol -> k -> *
- data Required
- data Optional
- data Lenient
- data Strict
- data IsSecure
- data AuthProtect (tag :: k) :: forall k. k -> *
- data EmptyAPI = EmptyAPI
- data Summary (sym :: Symbol)
- data Description (sym :: Symbol)
- data JSON
- data PlainText
- data FormUrlEncoded
- data OctetStream
- class Accept (ctype :: k) where
- class Accept ctype => MimeRender (ctype :: k) a where
- class Accept ctype => MimeUnrender (ctype :: k) a where
- data NoContent = NoContent
- type Capture = Capture' ([] :: [*])
- data Capture' (mods :: [*]) (sym :: Symbol) a
- data CaptureAll (sym :: Symbol) a
- data BasicAuth (realm :: Symbol) userData
- data BasicAuthData = BasicAuthData {}
- data a :<|> b = a :<|> b
- type Vault = Vault RealWorld
- class SBoolI (b :: Bool) where
- data SBool (b :: Bool) where
- serveDirectory :: FilePath -> ServerT Raw m
- serveDirectoryWith :: StaticSettings -> ServerT Raw m
- serveDirectoryEmbedded :: [(FilePath, ByteString)] -> ServerT Raw m
- serveDirectoryWebAppLookup :: ETagLookup -> FilePath -> ServerT Raw m
- serveDirectoryFileServer :: FilePath -> ServerT Raw m
- serveDirectoryWebApp :: FilePath -> ServerT Raw m
- layoutWithContext :: HasServer api context => Proxy api -> Context context -> Text
- layout :: HasServer api ([] :: [*]) => Proxy api -> Text
- hoistServer :: HasServer api ([] :: [*]) => Proxy api -> (forall x. m x -> n x) -> ServerT api m -> ServerT api n
- serveWithContext :: HasServer api context => Proxy api -> Context context -> Server api -> Application
- serve :: HasServer api ([] :: [*]) => Proxy api -> Server api -> Application
- emptyServer :: ServerT EmptyAPI m
- class HasServer (api :: k) (context :: [*]) where
- type Server (api :: k) = ServerT api Handler
- data EmptyServer
- data BasicAuthResult usr
- = Unauthorized
- | BadPassword
- | NoSuchUser
- | Authorized usr
- newtype BasicAuthCheck usr = BasicAuthCheck {
- unBasicAuthCheck :: BasicAuthData -> IO (BasicAuthResult usr)
- tweakResponse :: (RouteResult Response -> RouteResult Response) -> Router env -> Router env
- toApplication :: RoutingApplication -> Application
- runHandler :: Handler a -> IO (Either ServantErr a)
- runHandler' :: Handler a -> ExceptT ServantErr IO a
- err505 :: ServantErr
- err504 :: ServantErr
- err503 :: ServantErr
- err502 :: ServantErr
- err501 :: ServantErr
- err500 :: ServantErr
- err422 :: ServantErr
- err418 :: ServantErr
- err417 :: ServantErr
- err416 :: ServantErr
- err415 :: ServantErr
- err414 :: ServantErr
- err413 :: ServantErr
- err412 :: ServantErr
- err411 :: ServantErr
- err410 :: ServantErr
- err409 :: ServantErr
- err407 :: ServantErr
- err406 :: ServantErr
- err405 :: ServantErr
- err404 :: ServantErr
- err403 :: ServantErr
- err402 :: ServantErr
- err401 :: ServantErr
- err400 :: ServantErr
- err307 :: ServantErr
- err305 :: ServantErr
- err304 :: ServantErr
- err303 :: ServantErr
- err302 :: ServantErr
- err301 :: ServantErr
- err300 :: ServantErr
- data ServantErr = ServantErr {
- errHTTPCode :: Int
- errReasonPhrase :: String
- errBody :: ByteString
- errHeaders :: [Header]
- descendIntoNamedContext :: HasContextEntry context (NamedContext name subContext) => Proxy name -> Context context -> Context subContext
- data Context (contextTypes :: [*]) where
- EmptyContext :: Context ([] :: [*])
- (:.) :: Context (x ': xs)
- class HasContextEntry (context :: [*]) val where
- data NamedContext (name :: Symbol) (subContext :: [*]) = NamedContext (Context subContext)
- type Application = Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
- newtype Tagged (s :: k) b :: forall k. k -> * -> * = Tagged {
- unTagged :: b
- runMagicbaneHandler :: β -> RIO β α -> Handler α
- magicbaneApp :: forall β χ ψ. HasServer χ ψ => Proxy χ -> Context ψ -> β -> ServerT χ (RIO β) -> Application
- data RIO env a
Documentation
asProxyTypeOf :: a -> proxy a -> a #
asProxyTypeOf
is a type-restricted version of const
.
It is usually used as an infix operator, and its typing forces its first
argument (which is usually overloaded) to have the same type as the tag
of the second.
>>>
import Data.Word
>>>
:type asProxyTypeOf 123 (Proxy :: Proxy Word8)
asProxyTypeOf 123 (Proxy :: Proxy Word8) :: Word8
Note the lower-case proxy
in the definition. This allows any type
constructor with just one argument to be passed to the function, for example
we could also write
>>>
import Data.Word
>>>
:type asProxyTypeOf 123 (Just (undefined :: Word8))
asProxyTypeOf 123 (Just (undefined :: Word8)) :: Word8
data Proxy (t :: k) :: forall k. k -> * #
Proxy
is a type that holds no data, but has a phantom parameter of
arbitrary type (or even kind). Its use is to provide type information, even
though there is no value available of that type (or it may be too costly to
create one).
Historically,
is a safer alternative to the
Proxy
:: Proxy
a'undefined :: a'
idiom.
>>>
Proxy :: Proxy (Void, Int -> Int)
Proxy
Proxy can even hold types of higher kinds,
>>>
Proxy :: Proxy Either
Proxy
>>>
Proxy :: Proxy Functor
Proxy
>>>
Proxy :: Proxy complicatedStructure
Proxy
Instances
Generic1 (Proxy :: k -> *) | |
Monad (Proxy :: * -> *) | Since: base-4.7.0.0 |
Functor (Proxy :: * -> *) | Since: base-4.7.0.0 |
Applicative (Proxy :: * -> *) | Since: base-4.7.0.0 |
Foldable (Proxy :: * -> *) | Since: base-4.7.0.0 |
Defined in Data.Foldable fold :: Monoid m => Proxy m -> m # foldMap :: Monoid m => (a -> m) -> Proxy a -> m # foldr :: (a -> b -> b) -> b -> Proxy a -> b # foldr' :: (a -> b -> b) -> b -> Proxy a -> b # foldl :: (b -> a -> b) -> b -> Proxy a -> b # foldl' :: (b -> a -> b) -> b -> Proxy a -> b # foldr1 :: (a -> a -> a) -> Proxy a -> a # foldl1 :: (a -> a -> a) -> Proxy a -> a # elem :: Eq a => a -> Proxy a -> Bool # maximum :: Ord a => Proxy a -> a # minimum :: Ord a => Proxy a -> a # | |
Traversable (Proxy :: * -> *) | Since: base-4.7.0.0 |
ToJSON1 (Proxy :: * -> *) | |
Defined in Data.Aeson.Types.ToJSON liftToJSON :: (a -> Value) -> ([a] -> Value) -> Proxy a -> Value # liftToJSONList :: (a -> Value) -> ([a] -> Value) -> [Proxy a] -> Value # liftToEncoding :: (a -> Encoding) -> ([a] -> Encoding) -> Proxy a -> Encoding # liftToEncodingList :: (a -> Encoding) -> ([a] -> Encoding) -> [Proxy a] -> Encoding # | |
FromJSON1 (Proxy :: * -> *) | |
Alternative (Proxy :: * -> *) | Since: base-4.9.0.0 |
MonadPlus (Proxy :: * -> *) | Since: base-4.9.0.0 |
Eq1 (Proxy :: * -> *) | Since: base-4.9.0.0 |
Ord1 (Proxy :: * -> *) | Since: base-4.9.0.0 |
Defined in Data.Functor.Classes | |
Read1 (Proxy :: * -> *) | Since: base-4.9.0.0 |
Defined in Data.Functor.Classes | |
Show1 (Proxy :: * -> *) | Since: base-4.9.0.0 |
NFData1 (Proxy :: * -> *) | Since: deepseq-1.4.3.0 |
Defined in Control.DeepSeq | |
Hashable1 (Proxy :: * -> *) | |
Defined in Data.Hashable.Class | |
Bounded (Proxy t) | |
Enum (Proxy s) | Since: base-4.7.0.0 |
Eq (Proxy s) | Since: base-4.7.0.0 |
Data t => Data (Proxy t) | Since: base-4.7.0.0 |
Defined in Data.Data gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Proxy t -> c (Proxy t) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Proxy t) # toConstr :: Proxy t -> Constr # dataTypeOf :: Proxy t -> DataType # dataCast1 :: Typeable t0 => (forall d. Data d => c (t0 d)) -> Maybe (c (Proxy t)) # dataCast2 :: Typeable t0 => (forall d e. (Data d, Data e) => c (t0 d e)) -> Maybe (c (Proxy t)) # gmapT :: (forall b. Data b => b -> b) -> Proxy t -> Proxy t # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Proxy t -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Proxy t -> r # gmapQ :: (forall d. Data d => d -> u) -> Proxy t -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Proxy t -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Proxy t -> m (Proxy t) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Proxy t -> m (Proxy t) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Proxy t -> m (Proxy t) # | |
Ord (Proxy s) | Since: base-4.7.0.0 |
Read (Proxy t) | Since: base-4.7.0.0 |
Show (Proxy s) | Since: base-4.7.0.0 |
Ix (Proxy s) | Since: base-4.7.0.0 |
Generic (Proxy t) | |
Semigroup (Proxy s) | Since: base-4.9.0.0 |
Monoid (Proxy s) | Since: base-4.7.0.0 |
Hashable (Proxy a) | |
Defined in Data.Hashable.Class | |
ToJSON (Proxy a) | |
Defined in Data.Aeson.Types.ToJSON | |
FromJSON (Proxy a) | |
NFData (Proxy a) | Since: deepseq-1.4.0.0 |
Defined in Control.DeepSeq | |
type Rep1 (Proxy :: k -> *) | |
type Rep (Proxy t) | |
A concrete, promotable proxy type, for use at the kind level There are no instances for this because it is intended at the kind level only
type family If (cond :: Bool) (tru :: k) (fls :: k) :: k where ... #
Type-level If. If True a b
==> a
; If False a b
==> b
class ToHttpApiData a where #
Convert value to HTTP API data.
WARNING: Do not derive this using DeriveAnyClass
as the generated
instance will loop indefinitely.
toUrlPiece :: a -> Text #
Convert to URL path piece.
toEncodedUrlPiece :: a -> Builder #
Convert to a URL path piece, making sure to encode any special chars.
The default definition uses encodePathSegmentsRelative
,
but this may be overriden with a more efficient version.
toHeader :: a -> ByteString #
Convert to HTTP header value.
toQueryParam :: a -> Text #
Convert to query param value.
Instances
class FromHttpApiData a where #
Parse value from HTTP API data.
WARNING: Do not derive this using DeriveAnyClass
as the generated
instance will loop indefinitely.
parseUrlPiece :: Text -> Either Text a #
Parse URL path piece.
parseHeader :: ByteString -> Either Text a #
Parse HTTP header value.
parseQueryParam :: Text -> Either Text a #
Parse query param value.
Instances
Represents a general universal resource identifier using its component parts.
For example, for the URI
foo://anonymous@www.haskell.org:42/ghc?query#frag
the components are:
Instances
Eq URI | |
Data URI | |
Defined in Network.URI gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> URI -> c URI # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c URI # dataTypeOf :: URI -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c URI) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c URI) # gmapT :: (forall b. Data b => b -> b) -> URI -> URI # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> URI -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> URI -> r # gmapQ :: (forall d. Data d => d -> u) -> URI -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> URI -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> URI -> m URI # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> URI -> m URI # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> URI -> m URI # | |
Ord URI | |
Show URI | |
Generic URI | |
NFData URI | |
Defined in Network.URI | |
type Rep URI | |
Defined in Network.URI type Rep URI = D1 (MetaData "URI" "Network.URI" "network-uri-2.6.1.0-AstEwZoXrlUJQq4VkxaVo9" False) (C1 (MetaCons "URI" PrefixI True) ((S1 (MetaSel (Just "uriScheme") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 String) :*: S1 (MetaSel (Just "uriAuthority") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Maybe URIAuth))) :*: (S1 (MetaSel (Just "uriPath") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 String) :*: (S1 (MetaSel (Just "uriQuery") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 String) :*: S1 (MetaSel (Just "uriFragment") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 String))))) |
data HttpVersion #
HTTP Version.
Note that the Show instance is intended merely for debugging.
Instances
HTTP standard method (as defined by RFC 2616, and PATCH which is defined by RFC 5789).
Instances
throwError :: MonadError e m => e -> m a #
Is used within a monadic computation to begin exception processing.
allFieldLinks' :: (HasLink (ToServantApi routes), GenericServant routes (AsLink a), ToServant routes (AsLink a) ~ MkLink (ToServantApi routes) a) => (Link -> a) -> routes (AsLink a) #
More general version of allFieldLinks
.
Since: servant-0.14.1
allFieldLinks :: (HasLink (ToServantApi routes), GenericServant routes (AsLink Link), ToServant routes (AsLink Link) ~ MkLink (ToServantApi routes) Link) => routes (AsLink Link) #
Get all links as a record.
Since: servant-0.14.1
fieldLink' :: (IsElem endpoint (ToServantApi routes), HasLink endpoint, GenericServant routes AsApi) => (Link -> a) -> (routes AsApi -> endpoint) -> MkLink endpoint a #
More general version of fieldLink
Since: servant-0.14.1
fieldLink :: (IsElem endpoint (ToServantApi routes), HasLink endpoint, GenericServant routes AsApi) => (routes AsApi -> endpoint) -> MkLink endpoint Link #
Given an API record field, create a link for that route. Only the field's type is used.
data Record route = Record { _get :: route :- Capture "id" Int :> Get '[JSON] String , _put :: route :- ReqBody '[JSON] Int :> Put '[JSON] Bool } deriving (Generic
) getLink :: Int -> Link getLink =fieldLink
_get
Since: servant-0.14.1
allLinks :: HasLink api => Proxy api -> MkLink api Link #
Create all links in an API.
Note that the api
type must be restricted to the endpoints that have
valid links to them.
>>>
type API = "foo" :> Capture "name" Text :> Get '[JSON] Text :<|> "bar" :> Capture "name" Int :> Get '[JSON] Double
>>>
let fooLink :<|> barLink = allLinks (Proxy :: Proxy API)
>>>
:t fooLink
fooLink :: Text -> Link>>>
:t barLink
barLink :: Int -> Link
Note: nested APIs don't work well with this approach
>>>
:kind! MkLink (Capture "nest" Char :> (Capture "x" Int :> Get '[JSON] Int :<|> Capture "y" Double :> Get '[JSON] Double)) Link
MkLink (Capture "nest" Char :> (Capture "x" Int :> Get '[JSON] Int :<|> Capture "y" Double :> Get '[JSON] Double)) Link :: * = Char -> (Int -> Link) :<|> (Double -> Link)
:: (IsElem endpoint api, HasLink endpoint) | |
=> (Link -> a) | |
-> Proxy api | The whole API that this endpoint is a part of |
-> Proxy endpoint | The API endpoint you would like to point to |
-> MkLink endpoint a |
More general safeLink
.
:: (IsElem endpoint api, HasLink endpoint) | |
=> Proxy api | The whole API that this endpoint is a part of |
-> Proxy endpoint | The API endpoint you would like to point to |
-> MkLink endpoint Link |
Create a valid (by construction) relative URI with query params.
This function will only typecheck if endpoint
is part of the API api
linkURI' :: LinkArrayElementStyle -> Link -> URI #
Configurable linkURI
.
>>>
type API = "sum" :> QueryParams "x" Int :> Get '[JSON] Int
>>>
linkURI' LinkArrayElementBracket $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API) [1, 2, 3]
sum?x[]=1&x[]=2&x[]=3
>>>
linkURI' LinkArrayElementPlain $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API) [1, 2, 3]
sum?x=1&x=2&x=3
>>>
type API = "something" :> Get '[JSON] Int
>>>
linkURI $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API)
something
>>>
type API = "sum" :> QueryParams "x" Int :> Get '[JSON] Int
>>>
linkURI $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API) [1, 2, 3]
sum?x[]=1&x[]=2&x[]=3
>>>
type API = "foo/bar" :> Get '[JSON] Int
>>>
linkURI $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API)
foo%2Fbar
>>>
type SomeRoute = "abc" :> Capture "email" String :> Put '[JSON] ()
>>>
let someRoute = Proxy :: Proxy SomeRoute
>>>
safeLink someRoute someRoute "test@example.com"
Link {_segments = ["abc","test%40example.com"], _queryParams = []}
>>>
linkURI $ safeLink someRoute someRoute "test@example.com"
abc/test%40example.com
linkQueryParams :: Link -> [Param] #
linkSegments :: Link -> [String] #
A safe link datatype.
The only way of constructing a Link
is using safeLink
, which means any
Link
is guaranteed to be part of the mentioned API.
Instances
Show Link | |
ToHttpApiData Link | |
Defined in Servant.Links toUrlPiece :: Link -> Text # toEncodedUrlPiece :: Link -> Builder # toHeader :: Link -> ByteString # toQueryParam :: Link -> Text # |
Query parameter.
data LinkArrayElementStyle #
How to encode array query elements.
LinkArrayElementBracket | foo[]=1&foo[]=2 |
LinkArrayElementPlain | foo=1&foo=2 |
Instances
A type that specifies that an API record contains a set of links.
Since: servant-0.14.1
Instances
GenericMode (AsLink a) | |
Defined in Servant.Links | |
type (AsLink a) :- api | |
Defined in Servant.Links |
class HasLink (endpoint :: k) where #
Construct a toLink for an endpoint.
Instances
data WithNamedContext (name :: Symbol) (subContext :: [*]) subApi #
WithNamedContext
names a specific tagged context to use for the
combinators in the API. (See also in servant-server
,
Servant.Server.Context
.) For example:
type UseNamedContextAPI = WithNamedContext "myContext" '[String] ( ReqBody '[JSON] Int :> Get '[JSON] Int)
Both the ReqBody
and Get
combinators will use the WithNamedContext
with
type tag "myContext" as their context.
Context
s are only relevant for servant-server
.
For more information, see the tutorial.
Instances
HasLink sub => HasLink (WithNamedContext name context sub :: *) | |
Defined in Servant.Links type MkLink (WithNamedContext name context sub) a :: * # toLink :: (Link -> a) -> Proxy (WithNamedContext name context sub) -> Link -> MkLink (WithNamedContext name context sub) a # | |
(HasContextEntry context (NamedContext name subContext), HasServer subApi subContext) => HasServer (WithNamedContext name subContext subApi :: *) context | |
Defined in Servant.Server.Internal type ServerT (WithNamedContext name subContext subApi) m :: * # 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 # | |
type MkLink (WithNamedContext name context sub :: *) a | |
Defined in Servant.Links | |
type ServerT (WithNamedContext name subContext subApi :: *) m | |
Defined in Servant.Server.Internal |
type family Endpoints api :: [*] where ... #
Flatten API into a list of endpoints.
>>>
Refl :: Endpoints SampleAPI :~: '["hello" :> Verb 'GET 200 '[JSON] Int, "bye" :> (Capture "name" String :> Verb 'POST 200 '[JSON, PlainText] Bool)]
Refl
type family IsElem' a s :: Constraint #
You may use this type family to tell the type checker that your custom
type may be skipped as part of a link. This is useful for things like
that are optional in a URI and do not affect them if they are
omitted.QueryParam
>>>
data CustomThing
>>>
type instance IsElem' e (CustomThing :> s) = IsElem e s
Note that
is called, which will mutually recurse back to IsElem
if it exhausts all other options again.IsElem'
Once you have written a HasLink
instance for CustomThing
you are ready to go.
type family IsElem endpoint api :: Constraint where ... #
Closed type family, check if endpoint
is within api
.
Uses
if it exhausts all other options.IsElem'
>>>
ok (Proxy :: Proxy (IsElem ("hello" :> Get '[JSON] Int) SampleAPI))
OK
>>>
ok (Proxy :: Proxy (IsElem ("bye" :> Get '[JSON] Int) SampleAPI))
... ... Could not deduce... ...
An endpoint is considered within an api even if it is missing combinators that don't affect the URL:
>>>
ok (Proxy :: Proxy (IsElem (Get '[JSON] Int) (Header "h" Bool :> Get '[JSON] Int)))
OK
>>>
ok (Proxy :: Proxy (IsElem (Get '[JSON] Int) (ReqBody '[JSON] Bool :> Get '[JSON] Int)))
OK
- N.B.:*
IsElem a b
can be seen as capturing the notion of whether the URL represented bya
would match the URL represented byb
, *not* whether a request represented bya
matches the endpoints servingb
(for the latter, useIsIn
).
IsElem e (sa :<|> sb) = Or (IsElem e sa) (IsElem e sb) | |
IsElem (e :> sa) (e :> sb) = IsElem sa sb | |
IsElem sa (Header sym x :> sb) = IsElem sa sb | |
IsElem sa (ReqBody y x :> sb) = IsElem sa sb | |
IsElem (CaptureAll z y :> sa) (CaptureAll x y :> sb) = IsElem sa sb | |
IsElem (Capture z y :> sa) (Capture x y :> sb) = IsElem sa sb | |
IsElem sa (QueryParam x y :> sb) = IsElem sa sb | |
IsElem sa (QueryParams x y :> sb) = IsElem sa sb | |
IsElem sa (QueryFlag x :> sb) = IsElem sa sb | |
IsElem (Verb m s ct typ) (Verb m s ct' typ) = IsSubList ct ct' | |
IsElem e e = () | |
IsElem e a = IsElem' e a |
type family IsSubAPI sub api :: Constraint where ... #
Check whether sub
is a sub-API of api
.
>>>
ok (Proxy :: Proxy (IsSubAPI SampleAPI (SampleAPI :<|> Get '[JSON] Int)))
OK
>>>
ok (Proxy :: Proxy (IsSubAPI (SampleAPI :<|> Get '[JSON] Int) SampleAPI))
... ... Could not deduce... ...
This uses IsElem
for checking; thus the note there applies here.
type family AllIsElem (xs :: [*]) api :: Constraint where ... #
Check that every element of xs
is an endpoint of api
(using
).IsElem
type family IsIn endpoint api :: Constraint where ... #
Closed type family, check if endpoint
is exactly within api
.
>>>
ok (Proxy :: Proxy (IsIn ("hello" :> Get '[JSON] Int) SampleAPI))
OK
Unlike IsElem
, this requires an *exact* match.
>>>
ok (Proxy :: Proxy (IsIn (Get '[JSON] Int) (Header "h" Bool :> Get '[JSON] Int)))
... ... Could not deduce... ...
type family IsStrictSubAPI sub api :: Constraint where ... #
IsStrictSubAPI sub api = AllIsIn (Endpoints sub) api |
type family AllIsIn (xs :: [*]) api :: Constraint where ... #
Check that every element of xs
is an endpoint of api
(using
).IsIn
ok (Proxy :: Proxy (AllIsIn (Endpoints SampleAPI) SampleAPI)) OK
type family AppendList (xs :: [a]) (ys :: [a]) :: [a] where ... #
Append two type-level lists.
AppendList ([] :: [a]) (ys :: [a]) = ys | |
AppendList (x ': xs :: [a]) (ys :: [a]) = x ': AppendList xs ys |
type family IsSubList (a :: [t]) (b :: [t]) :: Constraint where ... #
type Elem (e :: t) (es :: [t]) = ElemGo e es es #
Check that a value is an element of a list:
>>>
ok (Proxy :: Proxy (Elem Bool '[Int, Bool]))
OK
>>>
ok (Proxy :: Proxy (Elem String '[Int, Bool]))
... ... [Char]...'[Int, Bool... ...
type family ElemGo (e :: t) (es :: [t]) (orig :: t1) :: Constraint where ... #
type family Or a b :: Constraint where ... #
If either a or b produce an empty constraint, produce an empty constraint.
data Verb (method :: k1) (statusCode :: Nat) (contentTypes :: [*]) a :: forall k1. k1 -> Nat -> [*] -> * -> * #
Verb
is a general type for representing HTTP verbs (a.k.a. methods). For
convenience, type synonyms for each verb with a 200 response code are
provided, but you are free to define your own:
>>>
type Post204 contentTypes a = Verb 'POST 204 contentTypes a
Instances
HasLink (Verb m s ct a :: *) | |
(AllCTRender ctypes a, ReflectMethod method, KnownNat status) => HasServer (Verb method status ctypes a :: *) context | |
Defined in Servant.Server.Internal 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 # | |
(AllCTRender ctypes a, ReflectMethod method, KnownNat status, GetHeaders (Headers h a)) => HasServer (Verb method status ctypes (Headers h a) :: *) context | |
Defined in Servant.Server.Internal 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 # | |
Generic (Verb method statusCode contentTypes a) | |
type MkLink (Verb m s ct a :: *) r | |
Defined in Servant.Links | |
type ServerT (Verb method status ctypes (Headers h a) :: *) m | |
type ServerT (Verb method status ctypes a :: *) m | |
Defined in Servant.Server.Internal | |
type Rep (Verb method statusCode contentTypes a) | |
type PostCreated = Verb POST 201 #
POST
with 201 status code.
type GetAccepted = Verb GET 202 #
GET
with 202 status code.
type PostAccepted = Verb POST 202 #
POST
with 202 status code.
type DeleteAccepted = Verb DELETE 202 #
DELETE
with 202 status code.
type PatchAccepted = Verb PATCH 202 #
PATCH
with 202 status code.
type PutAccepted = Verb PUT 202 #
PUT
with 202 status code.
type GetNonAuthoritative = Verb GET 203 #
GET
with 203 status code.
type PostNonAuthoritative = Verb POST 203 #
POST
with 203 status code.
type DeleteNonAuthoritative = Verb DELETE 203 #
DELETE
with 203 status code.
type PatchNonAuthoritative = Verb PATCH 203 #
PATCH
with 203 status code.
type PutNonAuthoritative = Verb PUT 203 #
PUT
with 203 status code.
type GetNoContent = Verb GET 204 #
GET
with 204 status code.
type PostNoContent = Verb POST 204 #
POST
with 204 status code.
type DeleteNoContent = Verb DELETE 204 #
DELETE
with 204 status code.
type PatchNoContent = Verb PATCH 204 #
PATCH
with 204 status code.
type PutNoContent = Verb PUT 204 #
PUT
with 204 status code.
type GetResetContent = Verb GET 205 #
GET
with 205 status code.
type PostResetContent = Verb POST 205 #
POST
with 205 status code.
type GetPartialContent = Verb GET 206 #
GET
with 206 status code.
class ReflectMethod (a :: k) where #
reflectMethod :: Proxy a -> Method #
Instances
ReflectMethod PATCH | |
Defined in Servant.API.Verbs reflectMethod :: Proxy PATCH -> Method # | |
ReflectMethod OPTIONS | |
Defined in Servant.API.Verbs reflectMethod :: Proxy OPTIONS -> Method # | |
ReflectMethod CONNECT | |
Defined in Servant.API.Verbs reflectMethod :: Proxy CONNECT -> Method # | |
ReflectMethod TRACE | |
Defined in Servant.API.Verbs reflectMethod :: Proxy TRACE -> Method # | |
ReflectMethod DELETE | |
Defined in Servant.API.Verbs reflectMethod :: Proxy DELETE -> Method # | |
ReflectMethod PUT | |
Defined in Servant.API.Verbs reflectMethod :: Proxy PUT -> Method # | |
ReflectMethod HEAD | |
Defined in Servant.API.Verbs reflectMethod :: Proxy HEAD -> Method # | |
ReflectMethod POST | |
Defined in Servant.API.Verbs reflectMethod :: Proxy POST -> Method # | |
ReflectMethod GET | |
Defined in Servant.API.Verbs reflectMethod :: Proxy GET -> Method # |
data (path :: k) :> a :: forall k. k -> * -> * infixr 4 #
The contained API (second argument) can be found under ("/" ++ path)
(path being the first argument).
Example:
>>>
-- GET /hello/world
>>>
-- returning a JSON encoded World value
>>>
type MyApi = "hello" :> "world" :> Get '[JSON] World
Instances
HasLink sub => HasLink (HttpVersion :> sub :: *) | |
Defined in Servant.Links type MkLink (HttpVersion :> sub) a :: * # toLink :: (Link -> a) -> Proxy (HttpVersion :> sub) -> Link -> MkLink (HttpVersion :> sub) a # | |
HasLink sub => HasLink (ReqBody' mods ct a :> sub :: *) | |
HasLink sub => HasLink (RemoteHost :> sub :: *) | |
Defined in Servant.Links type MkLink (RemoteHost :> sub) a :: * # toLink :: (Link -> a) -> Proxy (RemoteHost :> sub) -> Link -> MkLink (RemoteHost :> sub) a # | |
(KnownSymbol sym, ToHttpApiData v, HasLink sub, SBoolI (FoldRequired mods)) => HasLink (QueryParam' mods sym v :> sub :: *) | |
Defined in Servant.Links type MkLink (QueryParam' mods sym v :> sub) a :: * # toLink :: (Link -> a) -> Proxy (QueryParam' mods sym v :> sub) -> Link -> MkLink (QueryParam' mods sym v :> sub) a # | |
(KnownSymbol sym, ToHttpApiData v, HasLink sub) => HasLink (QueryParams sym v :> sub :: *) | |
Defined in Servant.Links type MkLink (QueryParams sym v :> sub) a :: * # toLink :: (Link -> a) -> Proxy (QueryParams sym v :> sub) -> Link -> MkLink (QueryParams sym v :> sub) a # | |
(KnownSymbol sym, HasLink sub) => HasLink (QueryFlag sym :> sub :: *) | |
HasLink sub => HasLink (Header' mods sym a :> sub :: *) | |
HasLink sub => HasLink (IsSecure :> sub :: *) | |
HasLink sub => HasLink (AuthProtect tag :> sub :: *) | |
Defined in Servant.Links type MkLink (AuthProtect tag :> sub) a :: * # toLink :: (Link -> a) -> Proxy (AuthProtect tag :> sub) -> Link -> MkLink (AuthProtect tag :> sub) a # | |
HasLink sub => HasLink (Summary s :> sub :: *) | |
HasLink sub => HasLink (Description s :> sub :: *) | |
Defined in Servant.Links type MkLink (Description s :> sub) a :: * # toLink :: (Link -> a) -> Proxy (Description s :> sub) -> Link -> MkLink (Description s :> sub) a # | |
(ToHttpApiData v, HasLink sub) => HasLink (Capture' mods sym v :> sub :: *) | |
(ToHttpApiData v, HasLink sub) => HasLink (CaptureAll sym v :> sub :: *) | |
Defined in Servant.Links type MkLink (CaptureAll sym v :> sub) a :: * # toLink :: (Link -> a) -> Proxy (CaptureAll sym v :> sub) -> Link -> MkLink (CaptureAll sym v :> sub) a # | |
HasLink sub => HasLink (BasicAuth realm a :> sub :: *) | |
HasLink sub => HasLink (Vault :> sub :: *) | |
(KnownSymbol sym, HasLink sub) => HasLink (sym :> sub :: *) | |
(TypeError (HasServerArrowKindError arr) :: Constraint) => HasServer (arr :> api :: *) 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 :: *) context | |
Defined in Servant.Server.Internal type ServerT (HttpVersion :> api) m :: * # 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 # | |
(AllCTUnrender list a, HasServer api context, SBoolI (FoldLenient mods)) => HasServer (ReqBody' mods list a :> api :: *) 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 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 :: *) context | |
Defined in Servant.Server.Internal type ServerT (RemoteHost :> api) m :: * # 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 :: *) 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 type ServerT (QueryParam' mods sym a :> api) m :: * # 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 :: *) 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 type ServerT (QueryParams sym a :> api) m :: * # 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 :: *) 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 :: *) 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 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 :: *) context | |
Defined in Servant.Server.Internal | |
HasServer api ctx => HasServer (Summary desc :> api :: *) ctx | Ignore |
Defined in Servant.Server.Internal | |
HasServer api ctx => HasServer (Description desc :> api :: *) ctx | Ignore |
Defined in Servant.Server.Internal type ServerT (Description desc :> api) m :: * # 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 :: *) 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 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 :: *) 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 type ServerT (CaptureAll capture a :> api) m :: * # 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 :: *) context | Basic Authentication |
Defined in Servant.Server.Internal 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 :: *) context | |
Defined in Servant.Server.Internal | |
(KnownSymbol path, HasServer api context) => HasServer (path :> api :: *) context | Make sure the incoming request starts with |
Defined in Servant.Server.Internal | |
type MkLink (HttpVersion :> sub :: *) a | |
Defined in Servant.Links | |
type MkLink (ReqBody' mods ct a :> sub :: *) r | |
type MkLink (RemoteHost :> sub :: *) a | |
Defined in Servant.Links | |
type MkLink (QueryParam' mods sym v :> sub :: *) a | |
Defined in Servant.Links type MkLink (QueryParam' mods sym v :> sub :: *) a = If (FoldRequired mods) v (Maybe v) -> MkLink sub a | |
type MkLink (QueryParams sym v :> sub :: *) a | |
Defined in Servant.Links | |
type MkLink (QueryFlag sym :> sub :: *) a | |
type MkLink (Header' mods sym a :> sub :: *) r | |
type MkLink (IsSecure :> sub :: *) a | |
type MkLink (AuthProtect tag :> sub :: *) a | |
Defined in Servant.Links | |
type MkLink (Summary s :> sub :: *) a | |
type MkLink (Description s :> sub :: *) a | |
Defined in Servant.Links | |
type MkLink (Capture' mods sym v :> sub :: *) a | |
type MkLink (CaptureAll sym v :> sub :: *) a | |
Defined in Servant.Links | |
type MkLink (BasicAuth realm a :> sub :: *) r | |
type MkLink (Vault :> sub :: *) a | |
type MkLink (sym :> sub :: *) a | |
Defined in Servant.Links | |
type ServerT (arr :> api :: *) m | |
Defined in Servant.Server.Internal | |
type ServerT (HttpVersion :> api :: *) m | |
Defined in Servant.Server.Internal | |
type ServerT (ReqBody' mods list a :> api :: *) m | |
Defined in Servant.Server.Internal | |
type ServerT (RemoteHost :> api :: *) m | |
Defined in Servant.Server.Internal | |
type ServerT (QueryParam' mods sym a :> api :: *) m | |
Defined in Servant.Server.Internal | |
type ServerT (QueryParams sym a :> api :: *) m | |
Defined in Servant.Server.Internal | |
type ServerT (QueryFlag sym :> api :: *) m | |
type ServerT (Header' mods sym a :> api :: *) m | |
Defined in Servant.Server.Internal | |
type ServerT (IsSecure :> api :: *) m | |
type ServerT (Summary desc :> api :: *) m | |
type ServerT (Description desc :> api :: *) m | |
Defined in Servant.Server.Internal | |
type ServerT (Capture' mods capture a :> api :: *) m | |
type ServerT (CaptureAll capture a :> api :: *) m | |
Defined in Servant.Server.Internal | |
type ServerT (BasicAuth realm usr :> api :: *) m | |
type ServerT (Vault :> api :: *) m | |
type ServerT (path :> api :: *) m | |
Defined in Servant.Server.Internal |
data Stream (method :: k1) (status :: Nat) framing contentType a :: forall k1. k1 -> Nat -> * -> * -> * -> * #
A Stream endpoint for a given method emits a stream of encoded values at a given Content-Type, delimited by a framing strategy. Stream endpoints always return response code 200 on success. Type synonyms are provided for standard methods.
Instances
HasLink (Stream m status fr ct a :: *) | |
(MimeRender ctype a, ReflectMethod method, KnownNat status, FramingRender framing ctype, ToStreamGenerator b a) => HasServer (Stream method status framing ctype b :: *) context | |
Defined in Servant.Server.Internal route :: Proxy (Stream method status framing ctype b) -> Context context -> Delayed env (Server (Stream method status framing ctype b)) -> Router env # hoistServerWithContext :: Proxy (Stream method status framing ctype b) -> Proxy context -> (forall x. m x -> n x) -> ServerT (Stream method status framing ctype b) m -> ServerT (Stream method status framing ctype b) n # | |
(MimeRender ctype a, ReflectMethod method, KnownNat status, FramingRender framing ctype, ToStreamGenerator b a, GetHeaders (Headers h b)) => HasServer (Stream method status framing ctype (Headers h b) :: *) context | |
Defined in Servant.Server.Internal route :: Proxy (Stream method status framing ctype (Headers h b)) -> Context context -> Delayed env (Server (Stream method status framing ctype (Headers h b))) -> Router env # hoistServerWithContext :: Proxy (Stream method status framing ctype (Headers h b)) -> Proxy context -> (forall x. m x -> n x) -> ServerT (Stream method status framing ctype (Headers h b)) m -> ServerT (Stream method status framing ctype (Headers h b)) n # | |
Generic (Stream method status framing contentType a) | |
Defined in Servant.API.Stream | |
type MkLink (Stream m status fr ct a :: *) r | |
Defined in Servant.Links | |
type ServerT (Stream method status framing ctype (Headers h b) :: *) m | |
type ServerT (Stream method status framing ctype b :: *) m | |
Defined in Servant.Server.Internal | |
type Rep (Stream method status framing contentType a) | |
type StreamPost = Stream POST 200 #
newtype StreamGenerator a #
Stream endpoints may be implemented as producing a StreamGenerator
-- a function that itself takes two emit functions -- the first to be used on the first value the stream emits, and the second to be used on all subsequent values (to allow interspersed framing strategies such as comma separation).
StreamGenerator | |
|
Instances
ToStreamGenerator (StreamGenerator a) a | |
Defined in Servant.API.Stream toStreamGenerator :: StreamGenerator a -> StreamGenerator a # |
class ToStreamGenerator a b | a -> b where #
ToStreamGenerator is intended to be implemented for types such as Conduit, Pipe, etc. By implementing this class, all such streaming abstractions can be used directly as endpoints.
toStreamGenerator :: a -> StreamGenerator b #
Instances
ToStreamGenerator (StreamGenerator a) a | |
Defined in Servant.API.Stream toStreamGenerator :: StreamGenerator a -> StreamGenerator a # |
newtype ResultStream a #
Clients reading from streaming endpoints can be implemented as producing a ResultStream
that captures the setup, takedown, and incremental logic for a read, being an IO continuation that takes a producer of Just either values or errors that terminates with a Nothing.
Instances
BuildFromStream a (ResultStream a) | |
Defined in Servant.API.Stream buildFromStream :: ResultStream a -> ResultStream a # |
class BuildFromStream a b where #
BuildFromStream is intended to be implemented for types such as Conduit, Pipe, etc. By implementing this class, all such streaming abstractions can be used directly on the client side for talking to streaming endpoints.
buildFromStream :: ResultStream a -> b #
Instances
BuildFromStream a (ResultStream a) | |
Defined in Servant.API.Stream buildFromStream :: ResultStream a -> ResultStream a # |
class FramingRender (strategy :: k) (a :: k1) where #
The FramingRender class provides the logic for emitting a framing strategy. The strategy emits a header, followed by boundary-delimited data, and finally a termination character. For many strategies, some of these will just be empty bytestrings.
header :: Proxy strategy -> Proxy a -> ByteString #
boundary :: Proxy strategy -> Proxy a -> BoundaryStrategy #
trailer :: Proxy strategy -> Proxy a -> ByteString #
Instances
FramingRender NoFraming (a :: k) | |
Defined in Servant.API.Stream | |
FramingRender NewlineFraming (a :: k) | |
Defined in Servant.API.Stream header :: Proxy NewlineFraming -> Proxy a -> ByteString # boundary :: Proxy NewlineFraming -> Proxy a -> BoundaryStrategy # trailer :: Proxy NewlineFraming -> Proxy a -> ByteString # | |
FramingRender NetstringFraming (a :: k) | |
Defined in Servant.API.Stream header :: Proxy NetstringFraming -> Proxy a -> ByteString # boundary :: Proxy NetstringFraming -> Proxy a -> BoundaryStrategy # trailer :: Proxy NetstringFraming -> Proxy a -> ByteString # |
data BoundaryStrategy #
The bracketing strategy generates things to precede and follow the content, as with netstrings. The intersperse strategy inserts seperators between things, as with newline framing. Finally, the general strategy performs an arbitrary rewrite on the content, to allow escaping rules and such.
data ByteStringParser a #
A type of parser that can never fail, and has different parsing strategies (incremental, or EOF) depending if more input can be sent. The incremental parser should return Nothing
if it would like to be sent a longer ByteString. If it returns a value, it also returns the remainder following that value.
ByteStringParser | |
|
class FramingUnrender (strategy :: k) (a :: k1) where #
The FramingUnrender class provides the logic for parsing a framing strategy. The outer ByteStringParser
strips the header from a stream of bytes, and yields a parser that can handle the remainder, stepwise. Each frame may be a ByteString, or a String indicating the error state for that frame. Such states are per-frame, so that protocols that can resume after errors are able to do so. Eventually this returns an empty ByteString to indicate termination.
unrenderFrames :: Proxy strategy -> Proxy a -> ByteStringParser (ByteStringParser (Either String ByteString)) #
Instances
FramingUnrender NoFraming (a :: k) | |
Defined in Servant.API.Stream unrenderFrames :: Proxy NoFraming -> Proxy a -> ByteStringParser (ByteStringParser (Either String ByteString)) # | |
FramingUnrender NewlineFraming (a :: k) | |
Defined in Servant.API.Stream unrenderFrames :: Proxy NewlineFraming -> Proxy a -> ByteStringParser (ByteStringParser (Either String ByteString)) # | |
FramingUnrender NetstringFraming (a :: k) | |
Defined in Servant.API.Stream unrenderFrames :: Proxy NetstringFraming -> Proxy a -> ByteStringParser (ByteStringParser (Either String ByteString)) # |
A framing strategy that does not do any framing at all, it just passes the input data This will be used most of the time with binary data, such as files
Instances
FramingRender NoFraming (a :: k) | |
Defined in Servant.API.Stream | |
FramingUnrender NoFraming (a :: k) | |
Defined in Servant.API.Stream unrenderFrames :: Proxy NoFraming -> Proxy a -> ByteStringParser (ByteStringParser (Either String ByteString)) # |
data NewlineFraming #
A simple framing strategy that has no header or termination, and inserts a newline character between each frame. This assumes that it is used with a Content-Type that encodes without newlines (e.g. JSON).
Instances
FramingRender NewlineFraming (a :: k) | |
Defined in Servant.API.Stream header :: Proxy NewlineFraming -> Proxy a -> ByteString # boundary :: Proxy NewlineFraming -> Proxy a -> BoundaryStrategy # trailer :: Proxy NewlineFraming -> Proxy a -> ByteString # | |
FramingUnrender NewlineFraming (a :: k) | |
Defined in Servant.API.Stream unrenderFrames :: Proxy NewlineFraming -> Proxy a -> ByteStringParser (ByteStringParser (Either String ByteString)) # |
data NetstringFraming #
The netstring framing strategy as defined by djb: http://cr.yp.to/proto/netstrings.txt
Instances
FramingRender NetstringFraming (a :: k) | |
Defined in Servant.API.Stream header :: Proxy NetstringFraming -> Proxy a -> ByteString # boundary :: Proxy NetstringFraming -> Proxy a -> BoundaryStrategy # trailer :: Proxy NetstringFraming -> Proxy a -> ByteString # | |
FramingUnrender NetstringFraming (a :: k) | |
Defined in Servant.API.Stream unrenderFrames :: Proxy NetstringFraming -> Proxy a -> ByteStringParser (ByteStringParser (Either String ByteString)) # |
noHeader :: AddHeader h v orig new => orig -> new #
Deliberately do not add a header to a value.
>>>
let example1 = noHeader "hi" :: Headers '[Header "someheader" Int] String
>>>
getHeaders example1
[]
addHeader :: AddHeader h v orig new => v -> orig -> new #
addHeader
adds a header to a response. Note that it changes the type of
the value in the following ways:
- A simple value is wrapped in "Headers '[hdr]":
>>>
let example1 = addHeader 5 "hi" :: Headers '[Header "someheader" Int] String;
>>>
getHeaders example1
[("someheader","5")]
- A value that already has a header has its new header *prepended* to the existing list:
>>>
let example1 = addHeader 5 "hi" :: Headers '[Header "someheader" Int] String;
>>>
let example2 = addHeader True example1 :: Headers '[Header "1st" Bool, Header "someheader" Int] String
>>>
getHeaders example2
[("1st","true"),("someheader","5")]
Note that while in your handlers type annotations are not required, since the type can be inferred from the API type, in other cases you may find yourself needing to add annotations.
Response Header objects. You should never need to construct one directly.
Instead, use addOptionalHeader
.
Headers | |
|
Instances
(KnownSymbol h, ToHttpApiData v) => AddHeader h v (Headers (fst ': rest) a) (Headers (Header h v ': (fst ': rest)) a) | |
Defined in Servant.API.ResponseHeaders addOptionalHeader :: ResponseHeader h v -> Headers (fst ': rest) a -> Headers (Header h v ': (fst ': rest)) a | |
Functor (Headers ls) | |
(AllCTRender ctypes a, ReflectMethod method, KnownNat status, GetHeaders (Headers h a)) => HasServer (Verb method status ctypes (Headers h a) :: *) context | |
Defined in Servant.Server.Internal 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 # | |
(MimeRender ctype a, ReflectMethod method, KnownNat status, FramingRender framing ctype, ToStreamGenerator b a, GetHeaders (Headers h b)) => HasServer (Stream method status framing ctype (Headers h b) :: *) context | |
Defined in Servant.Server.Internal route :: Proxy (Stream method status framing ctype (Headers h b)) -> Context context -> Delayed env (Server (Stream method status framing ctype (Headers h b))) -> Router env # hoistServerWithContext :: Proxy (Stream method status framing ctype (Headers h b)) -> Proxy context -> (forall x. m x -> n x) -> ServerT (Stream method status framing ctype (Headers h b)) m -> ServerT (Stream method status framing ctype (Headers h b)) n # | |
GetHeaders' hs => GetHeaders (Headers hs a) | |
Defined in Servant.API.ResponseHeaders getHeaders :: Headers hs a -> [Header] # | |
type ServerT (Verb method status ctypes (Headers h a) :: *) m | |
type ServerT (Stream method status framing ctype (Headers h b) :: *) m | |
data ResponseHeader (sym :: Symbol) a #
Instances
Functor (ResponseHeader sym) | |
Defined in Servant.API.ResponseHeaders fmap :: (a -> b) -> ResponseHeader sym a -> ResponseHeader sym b # (<$) :: a -> ResponseHeader sym b -> ResponseHeader sym a # | |
Eq a => Eq (ResponseHeader sym a) | |
Defined in Servant.API.ResponseHeaders (==) :: ResponseHeader sym a -> ResponseHeader sym a -> Bool # (/=) :: ResponseHeader sym a -> ResponseHeader sym a -> Bool # | |
Show a => Show (ResponseHeader sym a) | |
Defined in Servant.API.ResponseHeaders showsPrec :: Int -> ResponseHeader sym a -> ShowS # show :: ResponseHeader sym a -> String # showList :: [ResponseHeader sym a] -> ShowS # |
Instances
GetHeadersFromHList hs => GetHeaders (HList hs) | |
Defined in Servant.API.ResponseHeaders getHeaders :: HList hs -> [Header] # |
class BuildHeadersTo (hs :: [*]) where #
buildHeadersTo :: [Header] -> HList hs #
Note: if there are multiple occurences of a header in the argument, the values are interspersed with commas before deserialization (see RFC2616 Sec 4.2)
Instances
BuildHeadersTo ([] :: [*]) | |
Defined in Servant.API.ResponseHeaders buildHeadersTo :: [Header] -> HList [] # | |
(FromHttpApiData v, BuildHeadersTo xs, KnownSymbol h) => BuildHeadersTo (Header h v ': xs) | |
Defined in Servant.API.ResponseHeaders buildHeadersTo :: [Header0] -> HList (Header h v ': xs) # |
class GetHeaders ls where #
getHeaders :: ls -> [Header] #
Instances
GetHeadersFromHList hs => GetHeaders (HList hs) | |
Defined in Servant.API.ResponseHeaders getHeaders :: HList hs -> [Header] # | |
GetHeaders' hs => GetHeaders (Headers hs a) | |
Defined in Servant.API.ResponseHeaders getHeaders :: Headers hs a -> [Header] # |
class AddHeader (h :: Symbol) v orig new | h v orig -> new, new -> h, new -> v, new -> orig #
addOptionalHeader
Instances
(KnownSymbol h, ToHttpApiData v, new ~ Headers (Header h v ': ([] :: [*])) a) => AddHeader h v a new | |
Defined in Servant.API.ResponseHeaders addOptionalHeader :: ResponseHeader h v -> a -> new | |
(KnownSymbol h, ToHttpApiData v) => AddHeader h v (Headers (fst ': rest) a) (Headers (Header h v ': (fst ': rest)) a) | |
Defined in Servant.API.ResponseHeaders addOptionalHeader :: ResponseHeader h v -> Headers (fst ': rest) a -> Headers (Header h v ': (fst ': rest)) a |
type ReqBody = ReqBody' (Required ': (Strict ': ([] :: [*]))) #
Extract the request body as a value of type a
.
Example:
>>>
-- POST /books
>>>
type MyApi = "books" :> ReqBody '[JSON] Book :> Post '[JSON] Book
data ReqBody' (mods :: [*]) (contentTypes :: [*]) a #
Instances
HasLink sub => HasLink (ReqBody' mods ct a :> sub :: *) | |
(AllCTUnrender list a, HasServer api context, SBoolI (FoldLenient mods)) => HasServer (ReqBody' mods list a :> api :: *) 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 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 # | |
type MkLink (ReqBody' mods ct a :> sub :: *) r | |
type ServerT (ReqBody' mods list a :> api :: *) m | |
Defined in Servant.Server.Internal |
data RemoteHost #
Provides access to the host or IP address from which the HTTP request was sent.
Instances
HasLink sub => HasLink (RemoteHost :> sub :: *) | |
Defined in Servant.Links type MkLink (RemoteHost :> sub) a :: * # toLink :: (Link -> a) -> Proxy (RemoteHost :> sub) -> Link -> MkLink (RemoteHost :> sub) a # | |
HasServer api context => HasServer (RemoteHost :> api :: *) context | |
Defined in Servant.Server.Internal type ServerT (RemoteHost :> api) m :: * # 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 # | |
type MkLink (RemoteHost :> sub :: *) a | |
Defined in Servant.Links | |
type ServerT (RemoteHost :> api :: *) m | |
Defined in Servant.Server.Internal |
Endpoint for plugging in your own Wai Application
s.
The given Application
will get the request as received by the server, potentially with
a modified (stripped) pathInfo
if the Application
is being routed with :>
.
In addition to just letting you plug in your existing WAI Application
s,
this can also be used with serveDirectory to serve
static files stored in a particular directory on your filesystem
Instances
HasLink Raw | |
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" |
type MkLink Raw a | |
Defined in Servant.Links | |
type ServerT Raw m | |
Defined in Servant.Server.Internal |
type QueryParam = QueryParam' (Optional ': (Strict ': ([] :: [*]))) #
Lookup the value associated to the sym
query string parameter
and try to extract it as a value of type a
.
Example:
>>>
-- /books?author=<author name>
>>>
type MyApi = "books" :> QueryParam "author" Text :> Get '[JSON] [Book]
data QueryParam' (mods :: [*]) (sym :: Symbol) a #
QueryParam
which can be Required
, Lenient
, or modified otherwise.
Instances
(KnownSymbol sym, ToHttpApiData v, HasLink sub, SBoolI (FoldRequired mods)) => HasLink (QueryParam' mods sym v :> sub :: *) | |
Defined in Servant.Links type MkLink (QueryParam' mods sym v :> sub) a :: * # toLink :: (Link -> a) -> Proxy (QueryParam' mods sym v :> sub) -> Link -> MkLink (QueryParam' mods sym v :> sub) a # | |
(KnownSymbol sym, FromHttpApiData a, HasServer api context, SBoolI (FoldRequired mods), SBoolI (FoldLenient mods)) => HasServer (QueryParam' mods sym a :> api :: *) 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 type ServerT (QueryParam' mods sym a :> api) m :: * # 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 # | |
type MkLink (QueryParam' mods sym v :> sub :: *) a | |
Defined in Servant.Links type MkLink (QueryParam' mods sym v :> sub :: *) a = If (FoldRequired mods) v (Maybe v) -> MkLink sub a | |
type ServerT (QueryParam' mods sym a :> api :: *) m | |
Defined in Servant.Server.Internal |
data QueryParams (sym :: Symbol) a #
Lookup the values associated to the sym
query string parameter
and try to extract it as a value of type [a]
. This is typically
meant to support query string parameters of the form
param[]=val1¶m[]=val2
and so on. Note that servant doesn't actually
require the []
s and will fetch the values just fine with
param=val1¶m=val2
, too.
Example:
>>>
-- /books?authors[]=<author1>&authors[]=<author2>&...
>>>
type MyApi = "books" :> QueryParams "authors" Text :> Get '[JSON] [Book]
Instances
(KnownSymbol sym, ToHttpApiData v, HasLink sub) => HasLink (QueryParams sym v :> sub :: *) | |
Defined in Servant.Links type MkLink (QueryParams sym v :> sub) a :: * # toLink :: (Link -> a) -> Proxy (QueryParams sym v :> sub) -> Link -> MkLink (QueryParams sym v :> sub) a # | |
(KnownSymbol sym, FromHttpApiData a, HasServer api context) => HasServer (QueryParams sym a :> api :: *) 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 type ServerT (QueryParams sym a :> api) m :: * # 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 # | |
type MkLink (QueryParams sym v :> sub :: *) a | |
Defined in Servant.Links | |
type ServerT (QueryParams sym a :> api :: *) m | |
Defined in Servant.Server.Internal |
data QueryFlag (sym :: Symbol) #
Lookup a potentially value-less query string parameter
with boolean semantics. If the param sym
is there without any value,
or if it's there with value "true" or "1", it's interpreted as True
.
Otherwise, it's interpreted as False
.
Example:
>>>
-- /books?published
>>>
type MyApi = "books" :> QueryFlag "published" :> Get '[JSON] [Book]
Instances
(KnownSymbol sym, HasLink sub) => HasLink (QueryFlag sym :> sub :: *) | |
(KnownSymbol sym, HasServer api context) => HasServer (QueryFlag sym :> api :: *) 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 | |
type MkLink (QueryFlag sym :> sub :: *) a | |
type ServerT (QueryFlag sym :> api :: *) m | |
type Header = (Header' (Optional ': (Strict ': ([] :: [*]))) :: Symbol -> k -> *) #
Extract the given header's value as a value of type a
.
I.e. header sent by client, parsed by server.
Example:
>>>
newtype Referer = Referer Text deriving (Eq, Show)
>>>
>>>
-- GET /view-my-referer
>>>
type MyApi = "view-my-referer" :> Header "from" Referer :> Get '[JSON] Referer
data Header' (mods :: [*]) (sym :: Symbol) (a :: k) :: forall k. [*] -> Symbol -> k -> * #
Instances
(KnownSymbol h, ToHttpApiData v) => AddHeader h v (Headers (fst ': rest) a) (Headers (Header h v ': (fst ': rest)) a) | |
Defined in Servant.API.ResponseHeaders addOptionalHeader :: ResponseHeader h v -> Headers (fst ': rest) a -> Headers (Header h v ': (fst ': rest)) a | |
HasLink sub => HasLink (Header' mods sym a :> sub :: *) | |
(KnownSymbol sym, FromHttpApiData a, HasServer api context, SBoolI (FoldRequired mods), SBoolI (FoldLenient mods)) => HasServer (Header' mods sym a :> api :: *) 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 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 # | |
(KnownSymbol h, ToHttpApiData x, GetHeadersFromHList xs) => GetHeadersFromHList (Header h x ': xs) | |
Defined in Servant.API.ResponseHeaders getHeadersFromHList :: HList (Header h x ': xs) -> [Header0] | |
(KnownSymbol h, GetHeadersFromHList rest, ToHttpApiData v) => GetHeaders' (Header h v ': rest) | |
Defined in Servant.API.ResponseHeaders getHeaders' :: Headers (Header h v ': rest) a -> [Header0] | |
(FromHttpApiData v, BuildHeadersTo xs, KnownSymbol h) => BuildHeadersTo (Header h v ': xs) | |
Defined in Servant.API.ResponseHeaders buildHeadersTo :: [Header0] -> HList (Header h v ': xs) # | |
type MkLink (Header' mods sym a :> sub :: *) r | |
type ServerT (Header' mods sym a :> api :: *) m | |
Defined in Servant.Server.Internal |
Optional argument. Wrapped in Maybe
.
Instances
(KnownSymbol h, ToHttpApiData v) => AddHeader h v (Headers (fst ': rest) a) (Headers (Header h v ': (fst ': rest)) a) | |
Defined in Servant.API.ResponseHeaders addOptionalHeader :: ResponseHeader h v -> Headers (fst ': rest) a -> Headers (Header h v ': (fst ': rest)) a | |
(KnownSymbol h, ToHttpApiData x, GetHeadersFromHList xs) => GetHeadersFromHList (Header h x ': xs) | |
Defined in Servant.API.ResponseHeaders getHeadersFromHList :: HList (Header h x ': xs) -> [Header0] | |
(KnownSymbol h, GetHeadersFromHList rest, ToHttpApiData v) => GetHeaders' (Header h v ': rest) | |
Defined in Servant.API.ResponseHeaders getHeaders' :: Headers (Header h v ': rest) a -> [Header0] | |
(FromHttpApiData v, BuildHeadersTo xs, KnownSymbol h) => BuildHeadersTo (Header h v ': xs) | |
Defined in Servant.API.ResponseHeaders buildHeadersTo :: [Header0] -> HList (Header h v ': xs) # |
Strictly parsed argument. Not wrapped.
Instances
(KnownSymbol h, ToHttpApiData v) => AddHeader h v (Headers (fst ': rest) a) (Headers (Header h v ': (fst ': rest)) a) | |
Defined in Servant.API.ResponseHeaders addOptionalHeader :: ResponseHeader h v -> Headers (fst ': rest) a -> Headers (Header h v ': (fst ': rest)) a | |
(KnownSymbol h, ToHttpApiData x, GetHeadersFromHList xs) => GetHeadersFromHList (Header h x ': xs) | |
Defined in Servant.API.ResponseHeaders getHeadersFromHList :: HList (Header h x ': xs) -> [Header0] | |
(KnownSymbol h, GetHeadersFromHList rest, ToHttpApiData v) => GetHeaders' (Header h v ': rest) | |
Defined in Servant.API.ResponseHeaders getHeaders' :: Headers (Header h v ': rest) a -> [Header0] | |
(FromHttpApiData v, BuildHeadersTo xs, KnownSymbol h) => BuildHeadersTo (Header h v ': xs) | |
Defined in Servant.API.ResponseHeaders buildHeadersTo :: [Header0] -> HList (Header h v ': xs) # |
Was this request made over an SSL connection?
Note that this value will not tell you if the client originally
made this request over SSL, but rather whether the current
connection is SSL. The distinction lies with reverse proxies.
In many cases, the client will connect to a load balancer over SSL,
but connect to the WAI handler without SSL. In such a case,
the handlers would get NotSecure
, but from a user perspective,
there is a secure connection.
Secure | the connection to the server is secure (HTTPS) |
NotSecure | the connection to the server is not secure (HTTP) |
Instances
Eq IsSecure | |
Ord IsSecure | |
Defined in Servant.API.IsSecure | |
Read IsSecure | |
Show IsSecure | |
Generic IsSecure | |
HasLink sub => HasLink (IsSecure :> sub :: *) | |
HasServer api context => HasServer (IsSecure :> api :: *) context | |
Defined in Servant.Server.Internal | |
type Rep IsSecure | |
type MkLink (IsSecure :> sub :: *) a | |
type ServerT (IsSecure :> api :: *) m | |
data AuthProtect (tag :: k) :: forall k. k -> * #
A generalized Authentication combinator. Use this if you have a non-standard authentication technique.
NOTE: THIS API IS EXPERIMENTAL AND SUBJECT TO CHANGE.
Instances
HasLink sub => HasLink (AuthProtect tag :> sub :: *) | |
Defined in Servant.Links type MkLink (AuthProtect tag :> sub) a :: * # toLink :: (Link -> a) -> Proxy (AuthProtect tag :> sub) -> Link -> MkLink (AuthProtect tag :> sub) a # | |
type MkLink (AuthProtect tag :> sub :: *) a | |
Defined in Servant.Links |
An empty API: one which serves nothing. Morally speaking, this should be
the unit of :<|>
. Implementors of interpretations of API types should
treat EmptyAPI
as close to the unit as possible.
Instances
Bounded EmptyAPI | |
Enum EmptyAPI | |
Eq EmptyAPI | |
Show EmptyAPI | |
HasLink EmptyAPI | |
HasServer EmptyAPI context | The server for an type MyApi = "nothing" :> EmptyApi server :: Server MyApi server = emptyAPIServer |
type MkLink EmptyAPI a | |
Defined in Servant.Links | |
type ServerT EmptyAPI m | |
Defined in Servant.Server.Internal |
data Summary (sym :: Symbol) #
Add a short summary for (part of) API.
Example:
>>>
type MyApi = Summary "Get book by ISBN." :> "books" :> Capture "isbn" Text :> Get '[JSON] Book
data Description (sym :: Symbol) #
Add more verbose description for (part of) API.
Example:
>>>
:{
type MyApi = Description "This comment is visible in multiple Servant interpretations \ \and can be really long if necessary. \ \Haskell multiline support is not perfect \ \but it's still very readable." :> Get '[JSON] Book :}
Instances
HasLink sub => HasLink (Description s :> sub :: *) | |
Defined in Servant.Links type MkLink (Description s :> sub) a :: * # toLink :: (Link -> a) -> Proxy (Description s :> sub) -> Link -> MkLink (Description s :> sub) a # | |
HasServer api ctx => HasServer (Description desc :> api :: *) ctx | Ignore |
Defined in Servant.Server.Internal type ServerT (Description desc :> api) m :: * # 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 # | |
type MkLink (Description s :> sub :: *) a | |
Defined in Servant.Links | |
type ServerT (Description desc :> api :: *) m | |
Defined in Servant.Server.Internal |
Instances
Accept JSON | application/json |
Defined in Servant.API.ContentTypes | |
ToJSON a => MimeRender JSON a | |
Defined in Servant.API.ContentTypes mimeRender :: Proxy JSON -> a -> ByteString # | |
FromJSON a => MimeUnrender JSON a |
|
Defined in Servant.API.ContentTypes mimeUnrender :: Proxy JSON -> ByteString -> Either String a # mimeUnrenderWithType :: Proxy JSON -> MediaType -> ByteString -> Either String a # |
Instances
data FormUrlEncoded #
Instances
Accept FormUrlEncoded | application/x-www-form-urlencoded |
Defined in Servant.API.ContentTypes | |
ToForm a => MimeRender FormUrlEncoded a |
|
Defined in Servant.API.ContentTypes mimeRender :: Proxy FormUrlEncoded -> a -> ByteString # | |
FromForm a => MimeUnrender FormUrlEncoded a |
|
Defined in Servant.API.ContentTypes mimeUnrender :: Proxy FormUrlEncoded -> ByteString -> Either String a # mimeUnrenderWithType :: Proxy FormUrlEncoded -> MediaType -> ByteString -> Either String a # |
data OctetStream #
Instances
Accept OctetStream | application/octet-stream |
Defined in Servant.API.ContentTypes contentType :: Proxy OctetStream -> MediaType # | |
MimeRender OctetStream ByteString | |
Defined in Servant.API.ContentTypes mimeRender :: Proxy OctetStream -> ByteString -> ByteString0 # | |
MimeRender OctetStream ByteString | id |
Defined in Servant.API.ContentTypes mimeRender :: Proxy OctetStream -> ByteString -> ByteString # | |
MimeUnrender OctetStream ByteString | Right . toStrict |
Defined in Servant.API.ContentTypes mimeUnrender :: Proxy OctetStream -> ByteString0 -> Either String ByteString # mimeUnrenderWithType :: Proxy OctetStream -> MediaType -> ByteString0 -> Either String ByteString # | |
MimeUnrender OctetStream ByteString | Right . id |
Defined in Servant.API.ContentTypes mimeUnrender :: Proxy OctetStream -> ByteString -> Either String ByteString # mimeUnrenderWithType :: Proxy OctetStream -> MediaType -> ByteString -> Either String ByteString # |
class Accept (ctype :: k) where #
Instances of Accept
represent mimetypes. They are used for matching
against the Accept
HTTP header of the request, and for setting the
Content-Type
header of the response
Example:
>>>
import Network.HTTP.Media ((//), (/:))
>>>
data HTML
>>>
:{
instance Accept HTML where contentType _ = "text" // "html" /: ("charset", "utf-8") :}
contentType :: Proxy ctype -> MediaType #
contentTypes :: Proxy ctype -> NonEmpty MediaType #
Instances
Accept JSON | application/json |
Defined in Servant.API.ContentTypes | |
Accept PlainText | text/plain;charset=utf-8 |
Defined in Servant.API.ContentTypes | |
Accept FormUrlEncoded | application/x-www-form-urlencoded |
Defined in Servant.API.ContentTypes | |
Accept OctetStream | application/octet-stream |
Defined in Servant.API.ContentTypes contentType :: Proxy OctetStream -> MediaType # |
class Accept ctype => MimeRender (ctype :: k) a where #
Instantiate this class to register a way of serializing a type based
on the Accept
header.
Example:
data MyContentType instance Accept MyContentType where contentType _ = "example" // "prs.me.mine" /: ("charset", "utf-8") instance Show a => MimeRender MyContentType a where mimeRender _ val = pack ("This is MINE! " ++ show val) type MyAPI = "path" :> Get '[MyContentType] Int
mimeRender :: Proxy ctype -> a -> ByteString #
Instances
class Accept ctype => MimeUnrender (ctype :: k) a where #
Instantiate this class to register a way of deserializing a type based
on the request's Content-Type
header.
>>>
import Network.HTTP.Media hiding (Accept)
>>>
import qualified Data.ByteString.Lazy.Char8 as BSC
>>>
data MyContentType = MyContentType String
>>>
:{
instance Accept MyContentType where contentType _ = "example" // "prs.me.mine" /: ("charset", "utf-8") :}
>>>
:{
instance Read a => MimeUnrender MyContentType a where mimeUnrender _ bs = case BSC.take 12 bs of "MyContentType" -> return . read . BSC.unpack $ BSC.drop 12 bs _ -> Left "didn't start with the magic incantation" :}
>>>
type MyAPI = "path" :> ReqBody '[MyContentType] Int :> Get '[JSON] Int
mimeUnrender :: Proxy ctype -> ByteString -> Either String a #
mimeUnrenderWithType :: Proxy ctype -> MediaType -> ByteString -> Either String a #
Instances
A type for responses without content-body.
Instances
Eq NoContent | |
Read NoContent | |
Show NoContent | |
Generic NoContent | |
Accept ctyp => AllMimeRender (ctyp ': ([] :: [*])) NoContent | |
Defined in Servant.API.ContentTypes allMimeRender :: Proxy (ctyp ': []) -> NoContent -> [(MediaType, ByteString)] # | |
AllMime (ctyp ': (ctyp' ': ctyps)) => AllMimeRender (ctyp ': (ctyp' ': ctyps)) NoContent | |
Defined in Servant.API.ContentTypes allMimeRender :: Proxy (ctyp ': (ctyp' ': ctyps)) -> NoContent -> [(MediaType, ByteString)] # | |
type Rep NoContent | |
type Capture = Capture' ([] :: [*]) #
Capture a value from the request path under a certain type a
.
Example:
>>>
-- GET /books/:isbn
>>>
type MyApi = "books" :> Capture "isbn" Text :> Get '[JSON] Book
data Capture' (mods :: [*]) (sym :: Symbol) a #
Capture
which can be modified. For example with Description
.
Instances
(ToHttpApiData v, HasLink sub) => HasLink (Capture' mods sym v :> sub :: *) | |
(KnownSymbol capture, FromHttpApiData a, HasServer api context) => HasServer (Capture' mods capture a :> api :: *) 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 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 # | |
type MkLink (Capture' mods sym v :> sub :: *) a | |
type ServerT (Capture' mods capture a :> api :: *) m | |
data CaptureAll (sym :: Symbol) a #
Capture all remaining values from the request path under a certain type
a
.
Example:
>>>
-- GET /src/*
>>>
type MyAPI = "src" :> CaptureAll "segments" Text :> Get '[JSON] SourceFile
Instances
(ToHttpApiData v, HasLink sub) => HasLink (CaptureAll sym v :> sub :: *) | |
Defined in Servant.Links type MkLink (CaptureAll sym v :> sub) a :: * # toLink :: (Link -> a) -> Proxy (CaptureAll sym v :> sub) -> Link -> MkLink (CaptureAll sym v :> sub) a # | |
(KnownSymbol capture, FromHttpApiData a, HasServer api context) => HasServer (CaptureAll capture a :> api :: *) 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 type ServerT (CaptureAll capture a :> api) m :: * # 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 # | |
type MkLink (CaptureAll sym v :> sub :: *) a | |
Defined in Servant.Links | |
type ServerT (CaptureAll capture a :> api :: *) m | |
Defined in Servant.Server.Internal |
data BasicAuth (realm :: Symbol) userData #
Combinator for Basic Access Authentication.
- IMPORTANT*: Only use Basic Auth over HTTPS! Credentials are not hashed or encrypted. Note also that because the same credentials are sent on every request, Basic Auth is not as secure as some alternatives. Further, the implementation in servant-server does not protect against some types of timing attacks.
In Basic Auth, username and password are base64-encoded and transmitted via
the Authorization
header. Handshakes are not required, making it
relatively efficient.
Instances
HasLink sub => HasLink (BasicAuth realm a :> sub :: *) | |
(KnownSymbol realm, HasServer api context, HasContextEntry context (BasicAuthCheck usr)) => HasServer (BasicAuth realm usr :> api :: *) context | Basic Authentication |
Defined in Servant.Server.Internal 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 # | |
type MkLink (BasicAuth realm a :> sub :: *) r | |
type ServerT (BasicAuth realm usr :> api :: *) m | |
data BasicAuthData #
A simple datatype to hold data required to decorate a request
Union of two APIs, first takes precedence in case of overlap.
Example:
>>>
:{
type MyApi = "books" :> Get '[JSON] [Book] -- GET /books :<|> "books" :> ReqBody '[JSON] Book :> Post '[JSON] () -- POST /books :}
a :<|> b infixr 3 |
Instances
Functor ((:<|>) a) | |
Foldable ((:<|>) a) | |
Defined in Servant.API.Alternative fold :: Monoid m => (a :<|> m) -> m # foldMap :: Monoid m => (a0 -> m) -> (a :<|> a0) -> m # foldr :: (a0 -> b -> b) -> b -> (a :<|> a0) -> b # foldr' :: (a0 -> b -> b) -> b -> (a :<|> a0) -> b # foldl :: (b -> a0 -> b) -> b -> (a :<|> a0) -> b # foldl' :: (b -> a0 -> b) -> b -> (a :<|> a0) -> b # foldr1 :: (a0 -> a0 -> a0) -> (a :<|> a0) -> a0 # foldl1 :: (a0 -> a0 -> a0) -> (a :<|> a0) -> a0 # toList :: (a :<|> a0) -> [a0] # length :: (a :<|> a0) -> Int # elem :: Eq a0 => a0 -> (a :<|> a0) -> Bool # maximum :: Ord a0 => (a :<|> a0) -> a0 # minimum :: Ord a0 => (a :<|> a0) -> a0 # | |
Traversable ((:<|>) a) | |
(HasLink a, HasLink b) => HasLink (a :<|> b :: *) | |
(HasServer a context, HasServer b context) => HasServer (a :<|> b :: *) 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 = ... |
(Bounded a, Bounded b) => Bounded (a :<|> b) | |
(Eq a, Eq b) => Eq (a :<|> b) | |
(Show a, Show b) => Show (a :<|> b) | |
(Semigroup a, Semigroup b) => Semigroup (a :<|> b) | |
(Monoid a, Monoid b) => Monoid (a :<|> b) | |
type MkLink (a :<|> b :: *) r | |
type ServerT (a :<|> b :: *) m | |
type Vault = Vault RealWorld #
A persistent store for values of arbitrary types.
This variant is the simplest and creates keys in the IO
monad.
See the module Data.Vault.ST if you want to use it with the ST
monad instead.
serveDirectory :: FilePath -> ServerT Raw m #
Same as serveDirectoryFileServer
. It used to be the only
file serving function in servant pre-0.10 and will be kept
around for a few versions, but is deprecated.
serveDirectoryWith :: StaticSettings -> ServerT Raw m #
Alias for staticApp
. Lets you serve a directory
with arbitrary StaticSettings
. Useful when you want
particular settings not covered by the four other
variants. This is the most flexible method.
serveDirectoryEmbedded :: [(FilePath, ByteString)] -> ServerT Raw m #
Uses embeddedSettings
.
serveDirectoryWebAppLookup :: ETagLookup -> FilePath -> ServerT Raw m #
Same as serveDirectoryWebApp
, but uses webAppSettingsWithLookup
.
serveDirectoryFileServer :: FilePath -> ServerT Raw m #
Same as serveDirectoryWebApp
, but uses defaultFileServerSettings
.
serveDirectoryWebApp :: FilePath -> ServerT Raw m #
Serve anything under the specified directory as a Raw
endpoint.
type MyApi = "static" :> Raw server :: Server MyApi server = serveDirectoryWebApp "/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 serveDirectoryWebApp
handler in the last position, because servant will try to match the handlers
in order.
Corresponds to the defaultWebAppSettings
StaticSettings
value.
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 :<|> Raw
we 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.
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
serveWithContext :: HasServer api context => Proxy api -> Context context -> Server api -> Application #
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 app
emptyServer :: ServerT EmptyAPI m #
Server for EmptyAPI
class HasServer (api :: k) (context :: [*]) where #
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 |
(TypeError (HasServerArrowTypeError a b) :: Constraint) => HasServer (a -> b :: *) context | This instance prevents from accidentally using '->' instead of
|
(HasServer a context, HasServer b context) => HasServer (a :<|> b :: *) 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 = ... |
(HasContextEntry context (NamedContext name subContext), HasServer subApi subContext) => HasServer (WithNamedContext name subContext subApi :: *) context | |
Defined in Servant.Server.Internal type ServerT (WithNamedContext name subContext subApi) m :: * # 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 :: *) 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 :: *) context | |
Defined in Servant.Server.Internal type ServerT (HttpVersion :> api) m :: * # 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 # | |
(AllCTUnrender list a, HasServer api context, SBoolI (FoldLenient mods)) => HasServer (ReqBody' mods list a :> api :: *) 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 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 :: *) context | |
Defined in Servant.Server.Internal type ServerT (RemoteHost :> api) m :: * # 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 :: *) 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 type ServerT (QueryParam' mods sym a :> api) m :: * # 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 :: *) 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 type ServerT (QueryParams sym a :> api) m :: * # 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 :: *) 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 :: *) 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 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 :: *) context | |
Defined in Servant.Server.Internal | |
HasServer api ctx => HasServer (Summary desc :> api :: *) ctx | Ignore |
Defined in Servant.Server.Internal | |
HasServer api ctx => HasServer (Description desc :> api :: *) ctx | Ignore |
Defined in Servant.Server.Internal type ServerT (Description desc :> api) m :: * # 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 :: *) 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 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 :: *) 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 type ServerT (CaptureAll capture a :> api) m :: * # 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 :: *) context | Basic Authentication |
Defined in Servant.Server.Internal 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 :: *) context | |
Defined in Servant.Server.Internal | |
(KnownSymbol path, HasServer api context) => HasServer (path :> api :: *) context | Make sure the incoming request starts with |
Defined in Servant.Server.Internal | |
(AllCTRender ctypes a, ReflectMethod method, KnownNat status) => HasServer (Verb method status ctypes a :: *) context | |
Defined in Servant.Server.Internal 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 # | |
(AllCTRender ctypes a, ReflectMethod method, KnownNat status, GetHeaders (Headers h a)) => HasServer (Verb method status ctypes (Headers h a) :: *) context | |
Defined in Servant.Server.Internal 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 # | |
(MimeRender ctype a, ReflectMethod method, KnownNat status, FramingRender framing ctype, ToStreamGenerator b a) => HasServer (Stream method status framing ctype b :: *) context | |
Defined in Servant.Server.Internal route :: Proxy (Stream method status framing ctype b) -> Context context -> Delayed env (Server (Stream method status framing ctype b)) -> Router env # hoistServerWithContext :: Proxy (Stream method status framing ctype b) -> Proxy context -> (forall x. m x -> n x) -> ServerT (Stream method status framing ctype b) m -> ServerT (Stream method status framing ctype b) n # | |
(MimeRender ctype a, ReflectMethod method, KnownNat status, FramingRender framing ctype, ToStreamGenerator b a, GetHeaders (Headers h b)) => HasServer (Stream method status framing ctype (Headers h b) :: *) context | |
Defined in Servant.Server.Internal route :: Proxy (Stream method status framing ctype (Headers h b)) -> Context context -> Delayed env (Server (Stream method status framing ctype (Headers h b))) -> Router env # hoistServerWithContext :: Proxy (Stream method status framing ctype (Headers h b)) -> Proxy context -> (forall x. m x -> n x) -> ServerT (Stream method status framing ctype (Headers h b)) m -> ServerT (Stream method status framing ctype (Headers h b)) n # |
data EmptyServer #
Singleton type representing a server that serves an empty API.
Instances
Bounded EmptyServer | |
Defined in Servant.Server.Internal minBound :: EmptyServer # maxBound :: EmptyServer # | |
Enum EmptyServer | |
Defined in Servant.Server.Internal 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 (==) :: EmptyServer -> EmptyServer -> Bool # (/=) :: EmptyServer -> EmptyServer -> Bool # | |
Show EmptyServer | |
Defined in Servant.Server.Internal showsPrec :: Int -> EmptyServer -> ShowS # show :: EmptyServer -> String # showList :: [EmptyServer] -> ShowS # |
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
Instances
newtype BasicAuthCheck usr #
Datatype wrapping a function used to check authentication.
BasicAuthCheck | |
|
Instances
Functor BasicAuthCheck | |
Defined in Servant.Server.Internal.BasicAuth fmap :: (a -> b) -> BasicAuthCheck a -> BasicAuthCheck b # (<$) :: a -> BasicAuthCheck b -> BasicAuthCheck a # | |
Generic (BasicAuthCheck usr) | |
Defined in Servant.Server.Internal.BasicAuth type Rep (BasicAuthCheck usr) :: * -> * # 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.14.1-8QeZlk3HyJYB7GKYC8rKfC" True) (C1 (MetaCons "BasicAuthCheck" PrefixI True) (S1 (MetaSel (Just "unBasicAuthCheck") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (BasicAuthData -> IO (BasicAuthResult usr))))) |
tweakResponse :: (RouteResult Response -> RouteResult Response) -> Router env -> Router env #
Apply a transformation to the response of a Router
.
runHandler :: Handler a -> IO (Either ServantErr a) #
runHandler' :: Handler a -> ExceptT ServantErr IO a #
err505 :: ServantErr #
err505
HTTP Version not supported
Example usage:
failingHandler :: Handler () failingHandler = throwError $ err505 { errBody = "I support HTTP/4.0 only." }
err504 :: ServantErr #
err504
Gateway Time-out
Example:
failingHandler :: Handler () failingHandler = throwError $ err504 { errBody = "Backend foobar did not respond in 5 seconds." }
err503 :: ServantErr #
err503
Service Unavailable
Example:
failingHandler :: Handler () failingHandler = throwError $ err503 { errBody = "We're rewriting in PHP." }
err502 :: ServantErr #
err502
Bad Gateway
Example:
failingHandler :: Handler () failingHandler = throwError $ err502 { errBody = "Tried gateway foo, bar, and baz. None responded." }
err501 :: ServantErr #
err501
Not Implemented
Example:
failingHandler :: Handler () failingHandler = throwError $ err501 { errBody = "/v1/foo is not supported with quux in the request." }
err500 :: ServantErr #
err500
Internal Server Error
Example:
failingHandler :: Handler () failingHandler = throwError $ err500 { errBody = "Exception in module A.B.C:55. Have a great day!" }
err422 :: ServantErr #
err422
Unprocessable Entity
Example:
failingHandler :: Handler () failingHandler = throwError $ err422 { errBody = "I understood your request, but can't process it." }
err418 :: ServantErr #
err418
Expectation Failed
Example:
failingHandler :: Handler () failingHandler = throwError $ err418 { errBody = "Apologies, this is not a webserver but a teapot." }
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." }
err416 :: ServantErr #
err416
Request range not satisfiable
Example:
failingHandler :: Handler () failingHandler = throwError $ err416 { errBody = "Valid range is [0, 424242]." }
err415 :: ServantErr #
err415
Unsupported Media Type
Example:
failingHandler :: Handler () failingHandler = throwError $ err415 { errBody = "Supported media types: gif, png" }
err414 :: ServantErr #
err414
Request-URI Too Large
Example:
failingHandler :: Handler () failingHandler = throwError $ err414 { errBody = "Maximum length is 64." }
err413 :: ServantErr #
err413
Request Entity Too Large
Example:
failingHandler :: Handler () failingHandler = throwError $ err413 { errBody = "Request exceeded 64k." }
err412 :: ServantErr #
err412
Precondition Failed
Example:
failingHandler :: Handler () failingHandler = throwError $ err412 { errBody = "Precondition fail: x < 42 && y > 57" }
err411 :: ServantErr #
err410 :: ServantErr #
err410
Gone
Example:
failingHandler :: Handler () failingHandler = throwError $ err410 { errBody = "I know it was here at some point, but.. I blame bad luck." }
err409 :: ServantErr #
err409
Conflict
Example:
failingHandler :: Handler () failingHandler = throwError $ err409 { errBody = "Transaction conflicts with 59879cb56c7c159231eeacdd503d755f7e835f74" }
err407 :: ServantErr #
err407
Proxy Authentication Required
Example:
failingHandler :: Handler () failingHandler = throwError err407
err406 :: ServantErr #
err405 :: ServantErr #
err405
Method Not Allowed
Example:
failingHandler :: Handler () failingHandler = throwError $ err405 { errBody = "Your account privileges does not allow for this. Please pay $$$." }
err404 :: ServantErr #
err404
Not Found
Example:
failingHandler :: Handler () failingHandler = throwError $ err404 { errBody = "(╯°□°)╯︵ ┻━┻)." }
err403 :: ServantErr #
err403
Forbidden
Example:
failingHandler :: Handler () failingHandler = throwError $ err403 { errBody = "Please login first." }
err402 :: ServantErr #
err402
Payment Required
Example:
failingHandler :: Handler () failingHandler = throwError $ err402 { errBody = "You have 0 credits. Please give me $$$." }
err401 :: ServantErr #
err401
Unauthorized
Example:
failingHandler :: Handler () failingHandler = throwError $ err401 { errBody = "Your credentials are invalid." }
err400 :: ServantErr #
err400
Bad Request
Example:
failingHandler :: Handler () failingHandler = throwError $ err400 { errBody = "Your request makes no sense to me." }
err307 :: ServantErr #
err305 :: ServantErr #
err304 :: ServantErr #
err303 :: ServantErr #
err302 :: ServantErr #
err301 :: ServantErr #
err300 :: ServantErr #
err300
Multiple Choices
Example:
failingHandler :: Handler () failingHandler = throwError $ err300 { errBody = "I can't choose." }
data ServantErr #
ServantErr | |
|
Instances
Eq ServantErr | |
Defined in Servant.Server.Internal.ServantErr (==) :: ServantErr -> ServantErr -> Bool # (/=) :: ServantErr -> ServantErr -> Bool # | |
Read ServantErr | |
Defined in Servant.Server.Internal.ServantErr readsPrec :: Int -> ReadS ServantErr # readList :: ReadS [ServantErr] # readPrec :: ReadPrec ServantErr # readListPrec :: ReadPrec [ServantErr] # | |
Show ServantErr | |
Defined in Servant.Server.Internal.ServantErr showsPrec :: Int -> ServantErr -> ShowS # show :: ServantErr -> String # showList :: [ServantErr] -> ShowS # | |
Exception ServantErr | |
Defined in Servant.Server.Internal.ServantErr toException :: ServantErr -> SomeException # fromException :: SomeException -> Maybe ServantErr # displayException :: ServantErr -> String # | |
MonadError ServantErr Handler | |
Defined in Servant.Server.Internal.Handler throwError :: ServantErr -> Handler a # catchError :: Handler a -> (ServantErr -> Handler a) -> Handler a # |
descendIntoNamedContext :: HasContextEntry context (NamedContext name subContext) => Proxy name -> Context context -> Context subContext #
descendIntoNamedContext
allows you to access NamedContext
s. 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 subContext
subContext :: Context '[Bool]>>>
let parentContext = False :. (NamedContext subContext :: NamedContext "subContext" '[Bool]) :. EmptyContext
>>>
:type parentContext
parentContext :: Context '[Bool, NamedContext "subContext" '[Bool]]>>>
descendIntoNamedContext (Proxy :: Proxy "subContext") parentContext :: Context '[Bool]
True :. EmptyContext
data Context (contextTypes :: [*]) where #
Context
s 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 :. () :. EmptyContext
True :. () :. EmptyContext :: Context '[Bool, ()]
EmptyContext :: Context ([] :: [*]) | |
(:.) :: Context (x ': xs) infixr 5 |
class HasContextEntry (context :: [*]) val where #
This class is used to access context entries in Context
s. getContextEntry
returns the first value where the type matches:
>>>
getContextEntry (True :. False :. EmptyContext) :: Bool
True
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]) ...
getContextEntry :: Context context -> val #
Instances
HasContextEntry xs val => HasContextEntry (notIt ': xs) val | |
Defined in Servant.Server.Internal.Context getContextEntry :: Context (notIt ': xs) -> val # | |
HasContextEntry (val ': xs) val | |
Defined in Servant.Server.Internal.Context getContextEntry :: Context (val ': xs) -> val # |
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
Context
s.
NamedContext (Context subContext) |
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 -> * -> * #
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
ToJSON2 (Tagged :: * -> * -> *) | |
Defined in Data.Aeson.Types.ToJSON liftToJSON2 :: (a -> Value) -> ([a] -> Value) -> (b -> Value) -> ([b] -> Value) -> Tagged a b -> Value # liftToJSONList2 :: (a -> Value) -> ([a] -> Value) -> (b -> Value) -> ([b] -> Value) -> [Tagged a b] -> Value # liftToEncoding2 :: (a -> Encoding) -> ([a] -> Encoding) -> (b -> Encoding) -> ([b] -> Encoding) -> Tagged a b -> Encoding # liftToEncodingList2 :: (a -> Encoding) -> ([a] -> Encoding) -> (b -> Encoding) -> ([b] -> Encoding) -> [Tagged a b] -> Encoding # | |
FromJSON2 (Tagged :: * -> * -> *) | |
Defined in Data.Aeson.Types.FromJSON | |
Bitraversable (Tagged :: * -> * -> *) | |
Defined in Data.Tagged bitraverse :: Applicative f => (a -> f c) -> (b -> f d) -> Tagged a b -> f (Tagged c d) # | |
Bifoldable (Tagged :: * -> * -> *) | |
Bifunctor (Tagged :: * -> * -> *) | |
Eq2 (Tagged :: * -> * -> *) | |
Ord2 (Tagged :: * -> * -> *) | |
Defined in Data.Tagged | |
Read2 (Tagged :: * -> * -> *) | |
Defined in Data.Tagged 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 :: * -> * -> *) | |
Generic1 (Tagged s :: * -> *) | |
Monad (Tagged s) | |
Functor (Tagged s) | |
Applicative (Tagged s) | |
Foldable (Tagged s) | |
Defined in Data.Tagged 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) | |
ToJSON1 (Tagged a) | |
Defined in Data.Aeson.Types.ToJSON liftToJSON :: (a0 -> Value) -> ([a0] -> Value) -> Tagged a a0 -> Value # liftToJSONList :: (a0 -> Value) -> ([a0] -> Value) -> [Tagged a a0] -> Value # liftToEncoding :: (a0 -> Encoding) -> ([a0] -> Encoding) -> Tagged a a0 -> Encoding # liftToEncodingList :: (a0 -> Encoding) -> ([a0] -> Encoding) -> [Tagged a a0] -> Encoding # | |
FromJSON1 (Tagged a) | |
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 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 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 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 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 toRational :: Tagged s a -> Rational # | |
RealFloat a => RealFloat (Tagged s a) | |
Defined in Data.Tagged 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 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 fromString :: String -> Tagged s a # | |
Generic (Tagged s b) | |
Semigroup a => Semigroup (Tagged s a) | |
(Semigroup a, Monoid a) => Monoid (Tagged s a) | |
ToJSON b => ToJSON (Tagged a b) | |
Defined in Data.Aeson.Types.ToJSON | |
ToJSONKey b => ToJSONKey (Tagged a b) | |
Defined in Data.Aeson.Types.ToJSON toJSONKey :: ToJSONKeyFunction (Tagged a b) # toJSONKeyList :: ToJSONKeyFunction [Tagged a b] # | |
FromJSON b => FromJSON (Tagged a b) | |
FromJSONKey b => FromJSONKey (Tagged a b) | |
Defined in Data.Aeson.Types.FromJSON fromJSONKey :: FromJSONKeyFunction (Tagged a b) # fromJSONKeyList :: FromJSONKeyFunction [Tagged a b] # | |
Storable a => Storable (Tagged s a) | |
Defined in Data.Tagged | |
Bits a => Bits (Tagged s a) | |
Defined in Data.Tagged (.&.) :: 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 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 | |
type Rep1 (Tagged s :: * -> *) | |
Defined in Data.Tagged | |
type Rep (Tagged s b) | |
Defined in Data.Tagged |
runMagicbaneHandler :: β -> RIO β α -> Handler α Source #
magicbaneApp :: forall β χ ψ. HasServer χ ψ => Proxy χ -> Context ψ -> β -> ServerT χ (RIO β) -> Application Source #
Constructs a WAI application from an API definition, a Servant context (used for auth mainly), the app context and the actual action handlers.
The Reader+IO monad. This is different from a ReaderT
because:
- It's not a transformer, it hardcodes IO for simpler usage and error messages.
- Instances of typeclasses like
MonadLogger
are implemented using classes defined on the environment, instead of using an underlying monad.
Instances
MonadReader env (RIO env) | |
HasStateRef s env => MonadState s (RIO env) | |
(Monoid w, HasWriteRef w env) => MonadWriter w (RIO env) | |
Monad (RIO env) | |
Functor (RIO env) | |
Applicative (RIO env) | |
MonadIO (RIO env) | |
Defined in RIO.Prelude.RIO | |
MonadUnliftIO (RIO env) | |
Defined in RIO.Prelude.RIO | |
PrimMonad (RIO env) | |
MonadThrow (RIO env) | |
Defined in RIO.Prelude.RIO | |
type PrimState (RIO env) | |
Defined in RIO.Prelude.RIO | |
type StM (RIO env) a | |
Defined in RIO.Orphans |