-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A family of combinators for defining webservices APIs and serving them -- -- A family of combinators for defining webservices APIs and serving them -- -- You can learn about the basics in the tutorial. -- -- Here is a runnable example, with comments, that defines a dummy -- API and implements a webserver that serves this API, using this -- package. -- -- CHANGELOG @package servant-server @version 0.7.1 module Servant.Server.Internal.Context -- | Contexts are used to pass values to combinators. (They are -- not meant to be used to pass parameters to your handlers, i.e. -- they should not replace any custom ReaderT-monad-stack that -- you're using with Enter.) 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, ()]
--   
data Context contextTypes EmptyContext :: Context '[] (:.) :: x -> Context xs -> Context (x : xs) -- | This class is used to access context entries in Contexts. -- 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])
--   ...
--   
class HasContextEntry (context :: [*]) (val :: *) getContextEntry :: HasContextEntry context val => Context context -> val -- | Normally context entries are accessed by their types. In case you need -- to have multiple values of the same type in your Context and -- need to access them, we provide NamedContext. You can think of -- it as sub-namespaces for Contexts. data NamedContext (name :: Symbol) (subContext :: [*]) NamedContext :: (Context subContext) -> NamedContext -- | descendIntoNamedContext allows you to access -- NamedContexts. Usually you won't have to use it yourself but -- instead use a combinator like WithNamedContext. -- -- This is how descendIntoNamedContext works: -- --
--   >>> :set -XFlexibleContexts
--   
--   >>> let subContext = True :. EmptyContext
--   
--   >>> :type 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
--   
descendIntoNamedContext :: HasContextEntry context (NamedContext name subContext) => Proxy (name :: Symbol) -> Context context -> Context subContext instance GHC.Show.Show (Servant.Server.Internal.Context.Context '[]) instance (GHC.Show.Show a, GHC.Show.Show (Servant.Server.Internal.Context.Context as)) => GHC.Show.Show (Servant.Server.Internal.Context.Context (a : as)) instance GHC.Classes.Eq (Servant.Server.Internal.Context.Context '[]) instance (GHC.Classes.Eq a, GHC.Classes.Eq (Servant.Server.Internal.Context.Context as)) => GHC.Classes.Eq (Servant.Server.Internal.Context.Context (a : as)) instance Servant.Server.Internal.Context.HasContextEntry xs val => Servant.Server.Internal.Context.HasContextEntry (notIt : xs) val instance Servant.Server.Internal.Context.HasContextEntry (val : xs) val module Servant.Server.Internal.ServantErr data ServantErr ServantErr :: Int -> String -> ByteString -> [Header] -> ServantErr [errHTTPCode] :: ServantErr -> Int [errReasonPhrase] :: ServantErr -> String [errBody] :: ServantErr -> ByteString [errHeaders] :: ServantErr -> [Header] type Handler = ExceptT ServantErr IO responseServantErr :: ServantErr -> Response -- | err300 Multiple Choices -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err300 { errBody = "I can't choose." }
--   
err300 :: ServantErr -- | err301 Moved Permanently -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err301
--   
err301 :: ServantErr -- | err302 Found -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err302
--   
err302 :: ServantErr -- | err303 See Other -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err303
--   
err303 :: ServantErr -- | err304 Not Modified -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err304
--   
err304 :: ServantErr -- | err305 Use Proxy -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err305
--   
err305 :: ServantErr -- | err307 Temporary Redirect -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err307
--   
err307 :: ServantErr -- | err400 Bad Request -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err400 { errBody = "Your request makes no sense to me." }
--   
err400 :: ServantErr -- | err401 Unauthorized -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err401 { errBody = "Your credentials are invalid." }
--   
err401 :: ServantErr -- | err402 Payment Required -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err402 { errBody = "You have 0 credits. Please give me $$$." }
--   
err402 :: ServantErr -- | err403 Forbidden -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err403 { errBody = "Please login first." }
--   
err403 :: ServantErr -- | err404 Not Found -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err404 { errBody = "(╯°□°)╯︵ ┻━┻)." }
--   
err404 :: ServantErr -- | err405 Method Not Allowed -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err405 { errBody = "Your account privileges does not allow for this.  Please pay $$$." }
--   
err405 :: ServantErr -- | err406 Not Acceptable -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err406
--   
err406 :: ServantErr -- | err407 Proxy Authentication Required -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err407
--   
err407 :: ServantErr -- | err409 Conflict -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err409 { errBody = "Transaction conflicts with 59879cb56c7c159231eeacdd503d755f7e835f74" }
--   
err409 :: ServantErr -- | err410 Gone -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err410 { errBody = "I know it was here at some point, but.. I blame bad luck." }
--   
err410 :: ServantErr -- | err411 Length Required -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err411
--   
err411 :: ServantErr -- | err412 Precondition Failed -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err412 { errBody = "Precondition fail: x < 42 && y > 57" }
--   
err412 :: ServantErr -- | err413 Request Entity Too Large -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err413 { errBody = "Request exceeded 64k." }
--   
err413 :: ServantErr -- | err414 Request-URI Too Large -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err414 { errBody = "Maximum length is 64." }
--   
err414 :: ServantErr -- | err415 Unsupported Media Type -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err415 { errBody = "Supported media types:  gif, png" }
--   
err415 :: ServantErr -- | err416 Request range not satisfiable -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err416 { errBody = "Valid range is [0, 424242]." }
--   
err416 :: ServantErr -- | err417 Expectation Failed -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err417 { errBody = "I found a quux in the request.  This isn't going to work." }
--   
err417 :: ServantErr -- | err500 Internal Server Error -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err500 { errBody = "Exception in module A.B.C:55.  Have a great day!" }
--   
err500 :: ServantErr -- | err501 Not Implemented -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err501 { errBody = "/v1/foo is not supported with quux in the request." }
--   
err501 :: ServantErr -- | err502 Bad Gateway -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err502 { errBody = "Tried gateway foo, bar, and baz.  None responded." }
--   
err502 :: ServantErr -- | err503 Service Unavailable -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err503 { errBody = "We're rewriting in PHP." }
--   
err503 :: ServantErr -- | err504 Gateway Time-out -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err504 { errBody = "Backend foobar did not respond in 5 seconds." }
--   
err504 :: ServantErr -- | err505 HTTP Version not supported -- -- Example usage: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err505 { errBody = "I support HTTP/4.0 only." }
--   
err505 :: ServantErr instance GHC.Read.Read Servant.Server.Internal.ServantErr.ServantErr instance GHC.Classes.Eq Servant.Server.Internal.ServantErr.ServantErr instance GHC.Show.Show Servant.Server.Internal.ServantErr.ServantErr instance GHC.Exception.Exception Servant.Server.Internal.ServantErr.ServantErr module Servant.Server.Internal.RoutingApplication type RoutingApplication = Request the request, the field 'pathInfo' may be modified by url routing -> (RouteResult Response -> IO ResponseReceived) -> IO ResponseReceived -- | The result of matching against a path in the route tree. data RouteResult a -- | Keep trying other paths. The ServantErr should only be 404, -- 405 or 406. Fail :: ServantErr -> RouteResult a -- | Don't try other paths. FailFatal :: !ServantErr -> RouteResult a Route :: !a -> RouteResult a toApplication :: RoutingApplication -> Application -- | A Delayed is a representation of a handler with scheduled -- delayed checks that can trigger errors. -- -- Why would we want to delay checks? -- -- There are two reasons: -- --
    --
  1. In a straight-forward implementation, the order in which we -- perform checks will determine the error we generate. This is because -- once an error occurs, we would abort and not perform any subsequent -- checks, but rather return the current error.
  2. --
-- -- This is not a necessity: we could continue doing other checks, and -- choose the preferred error. However, that would in general mean more -- checking, which leads us to the other reason. -- --
    --
  1. We really want to avoid doing certain checks too early. For -- example, captures involve parsing, and are much more costly than -- static route matches. In particular, if several paths contain the -- "same" capture, we'd like as much as possible to avoid trying the same -- parse many times. Also tricky is the request body. Again, this -- involves parsing, but also, WAI makes obtaining the request body a -- side-effecting operation. We could/can work around this by manually -- caching the request body, but we'd rather keep the number of times we -- actually try to decode the request body to an absolute minimum.
  2. --
-- -- We prefer to have the following relative priorities of error codes: -- --
--   404
--   405 (bad method)
--   401 (unauthorized)
--   415 (unsupported media type)
--   400 (bad request)
--   406 (not acceptable)
--   
-- -- Therefore, while routing, we delay most checks so that they will -- ultimately occur in the right order. -- -- A Delayed contains three delayed blocks of tests, and the -- actual handler: -- --
    --
  1. Delayed captures. These can actually cause 404, and while they're -- costly, they should be done first among the delayed checks (at least -- as long as we do not decouple the check order from the error -- reporting, see above). Delayed captures can provide inputs to the -- actual handler.
  2. --
  3. Method check(s). This can cause a 405. On success, it does not -- provide an input for the handler. Method checks are comparatively -- cheap.
  4. --
  5. Body and accept header checks. The request body check can cause -- both 400 and 415. This provides an input to the handler. The accept -- header check can be performed as the final computation in this block. -- It can cause a 406.
  6. --
data Delayed env c Delayed :: (env -> DelayedIO captures) -> DelayedIO () -> DelayedIO auth -> DelayedIO body -> (captures -> auth -> body -> Request -> RouteResult c) -> Delayed env c [capturesD] :: Delayed env c -> env -> DelayedIO captures [methodD] :: Delayed env c -> DelayedIO () [authD] :: Delayed env c -> DelayedIO auth [bodyD] :: Delayed env c -> DelayedIO body [serverD] :: Delayed env c -> captures -> auth -> body -> Request -> RouteResult c -- | Computations used in a Delayed can depend on the incoming -- Request, may perform 'IO, and result in a 'RouteResult, meaning -- they can either suceed, fail (with the possibility to recover), or -- fail fatally. newtype DelayedIO a DelayedIO :: (Request -> IO (RouteResult a)) -> DelayedIO a [runDelayedIO] :: DelayedIO a -> Request -> IO (RouteResult a) -- | A Delayed without any stored checks. emptyDelayed :: RouteResult a -> Delayed env a -- | Fail with the option to recover. delayedFail :: ServantErr -> DelayedIO a -- | Fail fatally, i.e., without any option to recover. delayedFailFatal :: ServantErr -> DelayedIO a -- | Gain access to the incoming request. withRequest :: (Request -> DelayedIO a) -> DelayedIO a -- | Add a capture to the end of the capture block. addCapture :: Delayed env (a -> b) -> (Text -> DelayedIO a) -> Delayed (Text, env) b -- | Add a method check to the end of the method block. addMethodCheck :: Delayed env a -> DelayedIO () -> Delayed env a -- | Add an auth check to the end of the auth block. addAuthCheck :: Delayed env (a -> b) -> DelayedIO a -> Delayed env b -- | Add a body check to the end of the body block. addBodyCheck :: Delayed env (a -> b) -> DelayedIO a -> Delayed env b -- | Add an accept header check to the beginning of the body block. There -- is a tradeoff here. In principle, we'd like to take a bad body (400) -- response take precedence over a failed accept check (406). BUT to -- allow streaming the body, we cannot run the body check and then still -- backtrack. We therefore do the accept check before the body check, -- when we can still backtrack. There are other solutions to this, but -- they'd be more complicated (such as delaying the body check further so -- that it can still be run in a situation where we'd otherwise report -- 406). addAcceptCheck :: Delayed env a -> DelayedIO () -> Delayed env a -- | Many combinators extract information that is passed to the handler -- without the possibility of failure. In such a case, -- passToServer can be used. passToServer :: Delayed env (a -> b) -> (Request -> a) -> Delayed env b -- | Run a delayed server. Performs all scheduled operations in order, and -- passes the results from the capture and body blocks on to the actual -- handler. -- -- This should only be called once per request; otherwise the guarantees -- about effect and HTTP error ordering break down. runDelayed :: Delayed env a -> env -> Request -> IO (RouteResult a) -- | Runs a delayed server and the resulting action. Takes a continuation -- that lets us send a response. Also takes a continuation for how to -- turn the result of the delayed server into a response. runAction :: Delayed env (Handler a) -> env -> Request -> (RouteResult Response -> IO r) -> (a -> RouteResult Response) -> IO r instance GHC.Base.Functor Servant.Server.Internal.RoutingApplication.RouteResult instance GHC.Read.Read a => GHC.Read.Read (Servant.Server.Internal.RoutingApplication.RouteResult a) instance GHC.Show.Show a => GHC.Show.Show (Servant.Server.Internal.RoutingApplication.RouteResult a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Servant.Server.Internal.RoutingApplication.RouteResult a) instance GHC.Base.Functor (Servant.Server.Internal.RoutingApplication.Delayed env) instance GHC.Base.Functor Servant.Server.Internal.RoutingApplication.DelayedIO instance GHC.Base.Applicative Servant.Server.Internal.RoutingApplication.DelayedIO instance GHC.Base.Monad Servant.Server.Internal.RoutingApplication.DelayedIO instance Control.Monad.IO.Class.MonadIO Servant.Server.Internal.RoutingApplication.DelayedIO module Servant.Server.Internal.BasicAuth -- | 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 data BasicAuthResult usr Unauthorized :: BasicAuthResult usr BadPassword :: BasicAuthResult usr NoSuchUser :: BasicAuthResult usr Authorized :: usr -> BasicAuthResult usr -- | Datatype wrapping a function used to check authentication. newtype BasicAuthCheck usr BasicAuthCheck :: (BasicAuthData -> IO (BasicAuthResult usr)) -> BasicAuthCheck usr [unBasicAuthCheck] :: BasicAuthCheck usr -> BasicAuthData -> IO (BasicAuthResult usr) -- | Internal method to make a basic-auth challenge mkBAChallengerHdr :: ByteString -> Header -- | Find and decode an Authorization header from the request as -- Basic Auth decodeBAHdr :: Request -> Maybe BasicAuthData -- | Run and check basic authentication, returning the appropriate http -- error per the spec. runBasicAuth :: Request -> ByteString -> BasicAuthCheck usr -> DelayedIO usr instance GHC.Generics.Selector Servant.Server.Internal.BasicAuth.S1_0_0BasicAuthCheck instance GHC.Generics.Constructor Servant.Server.Internal.BasicAuth.C1_0BasicAuthCheck instance GHC.Generics.Datatype Servant.Server.Internal.BasicAuth.D1BasicAuthCheck instance GHC.Generics.Constructor Servant.Server.Internal.BasicAuth.C1_3BasicAuthResult instance GHC.Generics.Constructor Servant.Server.Internal.BasicAuth.C1_2BasicAuthResult instance GHC.Generics.Constructor Servant.Server.Internal.BasicAuth.C1_1BasicAuthResult instance GHC.Generics.Constructor Servant.Server.Internal.BasicAuth.C1_0BasicAuthResult instance GHC.Generics.Datatype Servant.Server.Internal.BasicAuth.D1BasicAuthResult instance GHC.Base.Functor Servant.Server.Internal.BasicAuth.BasicAuthCheck instance GHC.Generics.Generic (Servant.Server.Internal.BasicAuth.BasicAuthCheck usr) instance GHC.Base.Functor Servant.Server.Internal.BasicAuth.BasicAuthResult instance GHC.Generics.Generic (Servant.Server.Internal.BasicAuth.BasicAuthResult usr) instance GHC.Read.Read usr => GHC.Read.Read (Servant.Server.Internal.BasicAuth.BasicAuthResult usr) instance GHC.Show.Show usr => GHC.Show.Show (Servant.Server.Internal.BasicAuth.BasicAuthResult usr) instance GHC.Classes.Eq usr => GHC.Classes.Eq (Servant.Server.Internal.BasicAuth.BasicAuthResult usr) module Servant.Server.Internal.Router type Router env = Router' env RoutingApplication -- | Internal representation of a router. -- -- The first argument describes an environment type that is expected as -- extra input by the routers at the leaves. The environment is filled -- while running the router, with path components that can be used to -- process captures. data Router' env a -- | the map contains routers for subpaths (first path component used for -- lookup and removed afterwards), the list contains handlers for the -- empty path, to be tried in order StaticRouter :: (Map Text (Router' env a)) -> [env -> a] -> Router' env a -- | first path component is passed to the child router in its environment -- and removed afterwards CaptureRouter :: (Router' (Text, env) a) -> Router' env a -- | to be used for routes we do not know anything about RawRouter :: (env -> a) -> Router' env a -- | left-biased choice between two routers Choice :: (Router' env a) -> (Router' env a) -> Router' env a -- | Smart constructor for a single static path component. pathRouter :: Text -> Router' env a -> Router' env a -- | Smart constructor for a leaf, i.e., a router that expects the empty -- path. leafRouter :: (env -> a) -> Router' env a -- | Smart constructor for the choice between routers. We currently -- optimize the following cases: -- -- choice :: Router' env a -> Router' env a -> Router' env a -- | Datatype used for representing and debugging the structure of a -- router. Abstracts from the handlers at the leaves. -- -- Two Routers can be structurally compared by computing their -- RouterStructure using routerStructure and then testing -- for equality, see sameStructure. data RouterStructure StaticRouterStructure :: (Map Text RouterStructure) -> Int -> RouterStructure CaptureRouterStructure :: RouterStructure -> RouterStructure RawRouterStructure :: RouterStructure ChoiceStructure :: RouterStructure -> RouterStructure -> RouterStructure -- | Compute the structure of a router. -- -- Assumes that the request or text being passed in WithRequest -- or CaptureRouter does not affect the structure of the -- underlying tree. routerStructure :: Router' env a -> RouterStructure -- | Compare the structure of two routers. sameStructure :: Router' env a -> Router' env b -> Bool -- | Provide a textual representation of the structure of a router. routerLayout :: Router' env a -> Text -- | Apply a transformation to the response of a Router. tweakResponse :: (RouteResult Response -> RouteResult Response) -> Router env -> Router env -- | Interpret a router as an application. runRouter :: Router () -> RoutingApplication runRouterEnv :: Router env -> env -> RoutingApplication -- | Try a list of routing applications in order. We stop as soon as one -- fails fatally or succeeds. If all fail normally, we pick the "best" -- error. runChoice :: [env -> RoutingApplication] -> env -> RoutingApplication worseHTTPCode :: Int -> Int -> Bool instance GHC.Show.Show Servant.Server.Internal.Router.RouterStructure instance GHC.Classes.Eq Servant.Server.Internal.Router.RouterStructure instance GHC.Base.Functor (Servant.Server.Internal.Router.Router' env) module Servant.Server.Internal class HasServer layout context where type family ServerT layout (m :: * -> *) :: * route :: HasServer layout context => Proxy layout -> Context context -> Delayed env (Server layout) -> Router env type Server layout = ServerT layout Handler -- | A server for a :<|> b first tries to match the -- request against the route represented by a and if it fails -- tries b. You must provide a request handler for each route. -- --
--   type MyApi = "books" :> Get '[JSON] [Book] -- GET /books
--           :<|> "books" :> ReqBody Book :> Post '[JSON] Book -- POST /books
--   
--   server :: Server MyApi
--   server = listAllBooks :<|> postBook
--     where listAllBooks = ...
--           postBook book = ...
--   
-- | If you use Capture in one of the endpoints for your API, this -- automatically requires your server-side handler to be a function that -- takes an argument of the type specified by the Capture. This -- lets servant worry about getting it from the URL and turning it into a -- value of the type you specify. -- -- You can control how it'll be converted from Text to your type -- by simply providing an instance of FromHttpApiData for your -- type. -- -- Example: -- --
--   type MyApi = "books" :> Capture "isbn" Text :> Get '[JSON] Book
--   
--   server :: Server MyApi
--   server = getBook
--     where getBook :: Text -> Handler Book
--           getBook isbn = ...
--   
allowedMethodHead :: Method -> Request -> Bool allowedMethod :: Method -> Request -> Bool processMethodRouter :: Maybe (ByteString, ByteString) -> Status -> Method -> Maybe [(HeaderName, ByteString)] -> Request -> RouteResult Response methodCheck :: Method -> Request -> DelayedIO () acceptCheck :: (AllMime list) => Proxy list -> ByteString -> DelayedIO () methodRouter :: (AllCTRender ctypes a) => Method -> Proxy ctypes -> Status -> Delayed env (Handler a) -> Router env methodRouterHeaders :: (GetHeaders (Headers h v), AllCTRender ctypes v) => Method -> Proxy ctypes -> Status -> Delayed env (Handler (Headers h v)) -> Router env -- | If you use Header in one of the endpoints for your API, this -- automatically requires your server-side handler to be a function that -- takes an argument of the type specified by Header. This lets -- servant worry about extracting it from the request and turning it into -- a value of the type you specify. -- -- All it asks is for a FromHttpApiData instance. -- -- 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
--   
-- | If you use QueryParam "author" Text in one of the -- endpoints for your API, this automatically requires your server-side -- handler to be a function that takes an argument of type -- Maybe Text. -- -- This lets servant worry about looking it up in the query string and -- turning it into a value of the type you specify, enclosed in -- Maybe, because it may not be there and servant would then hand -- you Nothing. -- -- You can control how it'll be converted from Text to your type -- by simply providing an instance of FromHttpApiData for your -- type. -- -- 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...
--   
-- | If you use QueryParams "authors" Text in one of the -- endpoints for your API, this automatically requires your server-side -- handler to be a function that takes an argument of type -- [Text]. -- -- This lets servant worry about looking up 0 or more values in the query -- string associated to authors and turning each of them into a -- value of the type you specify. -- -- You can control how the individual values are converted from -- Text to your type by simply providing an instance of -- FromHttpApiData for your type. -- -- 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...
--   
-- | If you use QueryFlag "published" in one of the -- endpoints for your API, this automatically requires your server-side -- handler to be a function that takes an argument of type Bool. -- -- Example: -- --
--   type MyApi = "books" :> QueryFlag "published" :> Get '[JSON] [Book]
--   
--   server :: Server MyApi
--   server = getBooks
--     where getBooks :: Bool -> Handler [Book]
--           getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument...
--   
-- | Just pass the request to the underlying application and serve its -- response. -- -- Example: -- --
--   type MyApi = "images" :> Raw
--   
--   server :: Server MyApi
--   server = serveDirectory "/var/www/images"
--   
-- | If you use ReqBody in one of the endpoints for your API, this -- automatically requires your server-side handler to be a function that -- takes an argument of the type specified by ReqBody. The -- Content-Type header is inspected, and the list provided is -- used to attempt deserialization. If the request does not have a -- Content-Type header, it is treated as -- application/octet-stream (as specified in RFC7231. -- This lets servant worry about extracting it from the request and -- turning it into a value of the type you specify. -- -- All it asks is for a FromJSON instance. -- -- Example: -- --
--   type MyApi = "books" :> ReqBody '[JSON] Book :> Post '[JSON] Book
--   
--   server :: Server MyApi
--   server = postBook
--     where postBook :: Book -> Handler Book
--           postBook book = ...insert into your db...
--   
-- | Make sure the incoming request starts with "/path", strip it -- and pass the rest of the request path to sublayout. -- | Basic Authentication ct_wildcard :: ByteString instance (Servant.Server.Internal.HasServer a context, Servant.Server.Internal.HasServer b context) => Servant.Server.Internal.HasServer (a Servant.API.Alternative.:<|> b) context instance forall (k :: BOX) (capture :: GHC.TypeLits.Symbol) a (sublayout :: k) (context :: [*]). (GHC.TypeLits.KnownSymbol capture, Web.HttpApiData.Internal.FromHttpApiData a, Servant.Server.Internal.HasServer sublayout context) => Servant.Server.Internal.HasServer (Servant.API.Capture.Capture capture a Servant.API.Sub.:> sublayout) context instance forall (k :: BOX) (method :: k) (status :: GHC.TypeLits.Nat) (ctypes :: [*]) a (context :: [*]). (Servant.API.ContentTypes.AllCTRender ctypes a, Servant.API.Verbs.ReflectMethod method, GHC.TypeLits.KnownNat status) => Servant.Server.Internal.HasServer (Servant.API.Verbs.Verb method status ctypes a) context instance forall (k :: BOX) (method :: k) (status :: GHC.TypeLits.Nat) (ctypes :: [*]) (h :: [*]) a (context :: [*]). (Servant.API.ContentTypes.AllCTRender ctypes a, Servant.API.Verbs.ReflectMethod method, GHC.TypeLits.KnownNat status, Servant.API.ResponseHeaders.GetHeaders (Servant.API.ResponseHeaders.Headers h a)) => Servant.Server.Internal.HasServer (Servant.API.Verbs.Verb method status ctypes (Servant.API.ResponseHeaders.Headers h a)) context instance forall (k :: BOX) (sym :: GHC.TypeLits.Symbol) a (sublayout :: k) (context :: [*]). (GHC.TypeLits.KnownSymbol sym, Web.HttpApiData.Internal.FromHttpApiData a, Servant.Server.Internal.HasServer sublayout context) => Servant.Server.Internal.HasServer (Servant.API.Header.Header sym a Servant.API.Sub.:> sublayout) context instance forall (k :: BOX) (sym :: GHC.TypeLits.Symbol) a (sublayout :: k) (context :: [*]). (GHC.TypeLits.KnownSymbol sym, Web.HttpApiData.Internal.FromHttpApiData a, Servant.Server.Internal.HasServer sublayout context) => Servant.Server.Internal.HasServer (Servant.API.QueryParam.QueryParam sym a Servant.API.Sub.:> sublayout) context instance forall (k :: BOX) (sym :: GHC.TypeLits.Symbol) a (sublayout :: k) (context :: [*]). (GHC.TypeLits.KnownSymbol sym, Web.HttpApiData.Internal.FromHttpApiData a, Servant.Server.Internal.HasServer sublayout context) => Servant.Server.Internal.HasServer (Servant.API.QueryParam.QueryParams sym a Servant.API.Sub.:> sublayout) context instance forall (k :: BOX) (sym :: GHC.TypeLits.Symbol) (sublayout :: k) (context :: [*]). (GHC.TypeLits.KnownSymbol sym, Servant.Server.Internal.HasServer sublayout context) => Servant.Server.Internal.HasServer (Servant.API.QueryParam.QueryFlag sym Servant.API.Sub.:> sublayout) context instance Servant.Server.Internal.HasServer Servant.API.Raw.Raw context instance forall (k :: BOX) (list :: [*]) a (sublayout :: k) (context :: [*]). (Servant.API.ContentTypes.AllCTUnrender list a, Servant.Server.Internal.HasServer sublayout context) => Servant.Server.Internal.HasServer (Servant.API.ReqBody.ReqBody list a Servant.API.Sub.:> sublayout) context instance forall (k :: BOX) (path :: GHC.TypeLits.Symbol) (sublayout :: k) (context :: [*]). (GHC.TypeLits.KnownSymbol path, Servant.Server.Internal.HasServer sublayout context) => Servant.Server.Internal.HasServer (path Servant.API.Sub.:> sublayout) context instance forall (k :: BOX) (api :: k) (context :: [*]). Servant.Server.Internal.HasServer api context => Servant.Server.Internal.HasServer (Servant.API.RemoteHost.RemoteHost Servant.API.Sub.:> api) context instance forall (k :: BOX) (api :: k) (context :: [*]). Servant.Server.Internal.HasServer api context => Servant.Server.Internal.HasServer (Servant.API.IsSecure.IsSecure Servant.API.Sub.:> api) context instance forall (k :: BOX) (api :: k) (context :: [*]). Servant.Server.Internal.HasServer api context => Servant.Server.Internal.HasServer (Data.Vault.Lazy.Vault Servant.API.Sub.:> api) context instance forall (k :: BOX) (api :: k) (context :: [*]). Servant.Server.Internal.HasServer api context => Servant.Server.Internal.HasServer (Network.HTTP.Types.Version.HttpVersion Servant.API.Sub.:> api) context instance forall (k :: BOX) (realm :: GHC.TypeLits.Symbol) usr (api :: k) (context :: [*]). (GHC.TypeLits.KnownSymbol realm, Servant.Server.Internal.HasServer api context, Servant.Server.Internal.Context.HasContextEntry context (Servant.Server.Internal.BasicAuth.BasicAuthCheck usr)) => Servant.Server.Internal.HasServer (Servant.API.BasicAuth.BasicAuth realm usr Servant.API.Sub.:> api) context instance (Servant.Server.Internal.Context.HasContextEntry context (Servant.Server.Internal.Context.NamedContext name subContext), Servant.Server.Internal.HasServer subApi subContext) => Servant.Server.Internal.HasServer (Servant.API.WithNamedContext.WithNamedContext name subContext subApi) context -- | This module lets you implement Servers for defined APIs. You'll -- most likely just need serve. module Servant.Server -- | serve allows you to implement an API and produce a wai -- Application. -- -- Example: -- --
--   type MyApi = "books" :> Get '[JSON] [Book] -- GET /books
--           :<|> "books" :> ReqBody Book :> Post '[JSON] Book -- POST /books
--   
--   server :: Server MyApi
--   server = listAllBooks :<|> postBook
--     where listAllBooks = ...
--           postBook book = ...
--   
--   myApi :: Proxy MyApi
--   myApi = Proxy
--   
--   app :: Application
--   app = serve myApi server
--   
--   main :: IO ()
--   main = Network.Wai.Handler.Warp.run 8080 app
--   
serve :: (HasServer layout '[]) => Proxy layout -> Server layout -> Application serveWithContext :: (HasServer layout context) => Proxy layout -> Context context -> Server layout -> Application toApplication :: RoutingApplication -> Application class HasServer layout context where type family ServerT layout (m :: * -> *) :: * route :: HasServer layout context => Proxy layout -> Context context -> Delayed env (Server layout) -> Router env type Server layout = ServerT layout Handler type Handler = ExceptT ServantErr IO -- | 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] ()
--     :<|> "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: -- -- layout :: (HasServer layout '[]) => Proxy layout -> Text -- | Variant of layout that takes an additional Context. layoutWithContext :: (HasServer layout context) => Proxy layout -> Context context -> Text enter :: Enter typ arg ret => arg -> typ -> ret -- | A natural transformation from m to n. Used to -- enter particular datatypes. newtype (:~>) (m :: * -> *) (n :: * -> *) :: (* -> *) -> (* -> *) -> * Nat :: (forall a. m a -> n a) -> (:~>) [unNat] :: (:~>) -> forall a. m a -> n a -- | Like lift. liftNat :: (MonadTrans t, Monad m) => (:~>) m (t m) runReaderTNat :: r -> (:~>) (ReaderT r m) m evalStateTLNat :: Monad m => s -> (:~>) (StateT s m) m evalStateTSNat :: Monad m => s -> (:~>) (StateT s m) m -- | Like logWriterTSNat, but for strict WriterT. logWriterTLNat :: MonadIO m => (w -> IO ()) -> (:~>) (WriterT w m) m -- | Log the contents of WriterT with the function provided as the -- first argument, and return the value of the WriterT -- computation logWriterTSNat :: MonadIO m => (w -> IO ()) -> (:~>) (WriterT w m) m -- | Like mmorph's hoist. hoistNat :: (MFunctor t, Monad m) => (:~>) m n -> (:~>) (t m) (t n) -- | Like mmorph's embed. embedNat :: (MMonad t, Monad n) => (:~>) m (t n) -> (:~>) (t m) (t n) -- | Like mmorph's squash. squashNat :: (Monad m, MMonad t) => (:~>) (t (t m)) (t m) -- | Like mmorph's generalize. generalizeNat :: Applicative m => (:~>) Identity m -- | Apply a transformation to the response of a Router. tweakResponse :: (RouteResult Response -> RouteResult Response) -> Router env -> Router env -- | Contexts are used to pass values to combinators. (They are -- not meant to be used to pass parameters to your handlers, i.e. -- they should not replace any custom ReaderT-monad-stack that -- you're using with Enter.) 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, ()]
--   
data Context contextTypes EmptyContext :: Context '[] (:.) :: x -> Context xs -> Context (x : xs) -- | This class is used to access context entries in Contexts. -- 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])
--   ...
--   
class HasContextEntry (context :: [*]) (val :: *) getContextEntry :: HasContextEntry context val => Context context -> val -- | Normally context entries are accessed by their types. In case you need -- to have multiple values of the same type in your Context and -- need to access them, we provide NamedContext. You can think of -- it as sub-namespaces for Contexts. data NamedContext (name :: Symbol) (subContext :: [*]) NamedContext :: (Context subContext) -> NamedContext -- | descendIntoNamedContext allows you to access -- NamedContexts. Usually you won't have to use it yourself but -- instead use a combinator like WithNamedContext. -- -- This is how descendIntoNamedContext works: -- --
--   >>> :set -XFlexibleContexts
--   
--   >>> let subContext = True :. EmptyContext
--   
--   >>> :type 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
--   
descendIntoNamedContext :: HasContextEntry context (NamedContext name subContext) => Proxy (name :: Symbol) -> Context context -> Context subContext -- | Datatype wrapping a function used to check authentication. newtype BasicAuthCheck usr BasicAuthCheck :: (BasicAuthData -> IO (BasicAuthResult usr)) -> BasicAuthCheck usr [unBasicAuthCheck] :: BasicAuthCheck usr -> BasicAuthData -> IO (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 data BasicAuthResult usr Unauthorized :: BasicAuthResult usr BadPassword :: BasicAuthResult usr NoSuchUser :: BasicAuthResult usr Authorized :: usr -> BasicAuthResult usr data ServantErr ServantErr :: Int -> String -> ByteString -> [Header] -> ServantErr [errHTTPCode] :: ServantErr -> Int [errReasonPhrase] :: ServantErr -> String [errBody] :: ServantErr -> ByteString [errHeaders] :: ServantErr -> [Header] -- | err300 Multiple Choices -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err300 { errBody = "I can't choose." }
--   
err300 :: ServantErr -- | err301 Moved Permanently -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err301
--   
err301 :: ServantErr -- | err302 Found -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err302
--   
err302 :: ServantErr -- | err303 See Other -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err303
--   
err303 :: ServantErr -- | err304 Not Modified -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err304
--   
err304 :: ServantErr -- | err305 Use Proxy -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err305
--   
err305 :: ServantErr -- | err307 Temporary Redirect -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err307
--   
err307 :: ServantErr -- | err400 Bad Request -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err400 { errBody = "Your request makes no sense to me." }
--   
err400 :: ServantErr -- | err401 Unauthorized -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err401 { errBody = "Your credentials are invalid." }
--   
err401 :: ServantErr -- | err402 Payment Required -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err402 { errBody = "You have 0 credits. Please give me $$$." }
--   
err402 :: ServantErr -- | err403 Forbidden -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err403 { errBody = "Please login first." }
--   
err403 :: ServantErr -- | err404 Not Found -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err404 { errBody = "(╯°□°)╯︵ ┻━┻)." }
--   
err404 :: ServantErr -- | err405 Method Not Allowed -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err405 { errBody = "Your account privileges does not allow for this.  Please pay $$$." }
--   
err405 :: ServantErr -- | err406 Not Acceptable -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err406
--   
err406 :: ServantErr -- | err407 Proxy Authentication Required -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err407
--   
err407 :: ServantErr -- | err409 Conflict -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err409 { errBody = "Transaction conflicts with 59879cb56c7c159231eeacdd503d755f7e835f74" }
--   
err409 :: ServantErr -- | err410 Gone -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err410 { errBody = "I know it was here at some point, but.. I blame bad luck." }
--   
err410 :: ServantErr -- | err411 Length Required -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr err411
--   
err411 :: ServantErr -- | err412 Precondition Failed -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err412 { errBody = "Precondition fail: x < 42 && y > 57" }
--   
err412 :: ServantErr -- | err413 Request Entity Too Large -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err413 { errBody = "Request exceeded 64k." }
--   
err413 :: ServantErr -- | err414 Request-URI Too Large -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err414 { errBody = "Maximum length is 64." }
--   
err414 :: ServantErr -- | err415 Unsupported Media Type -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err415 { errBody = "Supported media types:  gif, png" }
--   
err415 :: ServantErr -- | err416 Request range not satisfiable -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err416 { errBody = "Valid range is [0, 424242]." }
--   
err416 :: ServantErr -- | err417 Expectation Failed -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err417 { errBody = "I found a quux in the request.  This isn't going to work." }
--   
err417 :: ServantErr -- | err500 Internal Server Error -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err500 { errBody = "Exception in module A.B.C:55.  Have a great day!" }
--   
err500 :: ServantErr -- | err501 Not Implemented -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err501 { errBody = "/v1/foo is not supported with quux in the request." }
--   
err501 :: ServantErr -- | err502 Bad Gateway -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err502 { errBody = "Tried gateway foo, bar, and baz.  None responded." }
--   
err502 :: ServantErr -- | err503 Service Unavailable -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err503 { errBody = "We're rewriting in PHP." }
--   
err503 :: ServantErr -- | err504 Gateway Time-out -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err504 { errBody = "Backend foobar did not respond in 5 seconds." }
--   
err504 :: ServantErr -- | err505 HTTP Version not supported -- -- Example usage: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwErr $ err505 { errBody = "I support HTTP/4.0 only." }
--   
err505 :: ServantErr -- | This module defines a sever-side handler that lets you serve static -- files. -- -- module Servant.Utils.StaticFiles -- | Serve anything under the specified directory as a Raw endpoint. -- --
--   type MyApi = "static" :> Raw
--   
--   server :: Server MyApi
--   server = serveDirectory "/var/www"
--   
-- -- would capture any request to /static/<something> and -- look for <something> under /var/www. -- -- It will do its best to guess the MIME type for that file, based on the -- extension, and send an appropriate Content-Type header if -- possible. -- -- If your goal is to serve HTML, CSS and Javascript files that use the -- rest of the API as a webapp backend, you will most likely not want the -- static files to be hidden behind a /static/ prefix. In that -- case, remember to put the serveDirectory handler in the last -- position, because servant will try to match the handlers in -- order. serveDirectory :: FilePath -> Server Raw module Servant -- | A concrete, poly-kinded proxy type data Proxy (t :: k) :: k -> * Proxy :: Proxy -- | Is used within a monadic computation to begin exception processing. throwError :: MonadError e m => forall a. e -> m a module Servant.Server.Experimental.Auth -- | Specify the type of data returned after we've authenticated a request. -- quite often this is some User datatype. -- -- NOTE: THIS API IS EXPERIMENTAL AND SUBJECT TO CHANGE -- | Handlers for AuthProtected resources -- -- NOTE: THIS API IS EXPERIMENTAL AND SUBJECT TO CHANGE newtype AuthHandler r usr AuthHandler :: (r -> Handler usr) -> AuthHandler r usr [unAuthHandler] :: AuthHandler r usr -> r -> Handler usr -- | NOTE: THIS API IS EXPERIMENTAL AND SUBJECT TO CHANGE mkAuthHandler :: (r -> Handler usr) -> AuthHandler r usr -- | Known orphan instance. instance GHC.Generics.Selector Servant.Server.Experimental.Auth.S1_0_0AuthHandler instance GHC.Generics.Constructor Servant.Server.Experimental.Auth.C1_0AuthHandler instance GHC.Generics.Datatype Servant.Server.Experimental.Auth.D1AuthHandler instance GHC.Generics.Generic (Servant.Server.Experimental.Auth.AuthHandler r usr) instance forall (k :: BOX) (k1 :: BOX) (tag :: k1) (api :: k) (context :: [*]). (Servant.Server.Internal.HasServer api context, Servant.Server.Internal.Context.HasContextEntry context (Servant.Server.Experimental.Auth.AuthHandler Network.Wai.Internal.Request (Servant.Server.Experimental.Auth.AuthServerData (Servant.API.Experimental.Auth.AuthProtect tag)))) => Servant.Server.Internal.HasServer (Servant.API.Experimental.Auth.AuthProtect tag Servant.API.Sub.:> api) context