Reference
Here is the list of main functions, types and classes
How to build server
-- server on path
(/.) :: ToServer a => Path -> a -> Server (MonadOf m)
-- alternative cases for server:
mconcat, (<>)
-- | take sub-server at path
atPath :: Path -> Server m -> Server m
toServer :: ToServer a => a -> Server (MonadOf m)
How to run server
runServer :: Int -> Server IO -> IO ()
runServer' :: ServerConfig -> Int -> Server IO -> IO ()
Server presets
Mig- generic typesMig.IO-IO-based servers with generic return typesMig.Json- JSON-based serversMig.Html- HTML-based serversMig.Json.IO- JSON and IO-based serversMig.Html.IO- HTML and IO-based servers
Media types
* Json
* Text
* Html
* FormUrlEncoded
* AnyMedia
* OctetStream
Request inputs
-- required query parameter
newtype Body media value = Body value
-- required query parameter
newtype Query name value = Query value
-- optional query parameter
newtype Optional name value = Optional (Maybe value)
-- required header parameter
newtype Header name value = Header value
-- optional header parameter
newtype OptionalHeader name value = OptionalHeader (Maybe value)
-- capture in path parameter
newtype Capture name value = Capture value
-- boolean query flag parameter
newtype QueryFlag name = QueryFlag Bool
-- Is connection made over SSL
newtype IsSecure = IsSecure Bool
-- full path with query parameters
newtype PathInfo = Path [Text]
-- | low-level request
newtype RawRequest = RawRequest Request
Request outputs
-- | generic route handler
newtype Send method m a = Send (m a)
-- Sepcific methos
type Get m a = Send GET m a
type Post m a = Send POST m a
...
-- Response where type of the value and error are the same
-- or only succesful result is expected
data Resp media a = Resp ...
-- Response where error and result have different types but media type is the same
data RespOr media err a = RespOr ...
The response type class:
class IsResp a where
-- | the type of response body value
type RespBody a :: Type
-- | the type of an error
type RespError a :: Type
-- | Returns valid repsonse with 200 status
ok :: RespBody a -> a
-- | Returns an error with given status
bad :: Status -> RespError a -> a
-- | response with no content
noContent :: Status -> a
-- | Add some header to the response
addHeaders :: ResponseHeaders -> a -> a
-- | Sets repsonse status
setStatus :: Status -> a -> a
-- | Set the media type of the response
setMedia :: MediaType -> a -> a
-- | Reads the media type by response type
getMedia :: MediaType
-- | Converts value to low-level response
toResponse :: a -> Response
setHeader :: (IsResp a, ToHttpApiData h) => HeaderName -> h -> a -> a
-- | Bad request. The @bad@ response with 400 status.
badReq :: (IsResp a) => RespError a -> a
-- | Internal server error. The @bad@ response with 500 status.
internalServerError :: (IsResp a) => RespError a -> a
-- | Not implemented route. The @bad@ response with 501 status.
notImplemented :: (IsResp a) => RespError a -> a
-- | Redirect to url. It is @bad@ response with 302 status
-- and set header of "Location" to a given URL.
redirect :: (IsResp a) => Text -> a
Plugins
applyPlugin, ($:) :: ToPlugin a =>
a -> Server (MonadOf a) -> Server (MonadOf a)
-- composition of plugins:
Monoid(..): mconcat, (<>), mempty
specific servers
-- | add wagger to server
withSwagger :: SwaggerConfig m -> Server m -> Server m
-- | add link from one route to another
addPathLink :: Path -> Path -> Server m
-- static files
staticFiles :: [(FilePath, ByteString)] -> Server m
specific plugins
-- prepend or append some acction to all routes
prependServerAction, appendServerAction :: MonadIO m => m () -> Plugin m
-- change the response
processResponse :: (m (Maybe Response) -> m (Maybe Response)) -> Plugin m
-- only secure routes are allowed
whenSecure :: forall m. (MonadIO m) => Plugin m
-- logging with putStrLn for debug traces
logHttp :: Verbosity -> Plugin m
-- logging with custom logger
logHttpBy :: (Json.Value -> m ()) -> Verbosity -> Plugin m
-- | simple authorization
withHeaderAuth :: WithHeaderAuth -> Plugin m
How to use Reader
-- Derive instance of HasServer class for your Reader-IO based application:
newtype App a = App (ReaderT Env IO a)
deriving newtype (Functor, Applicative, Monad, MonadReader Env, MonadIO, HasServer)
renderServer :: Server App -> Env -> IO (Server IO)
OpenApi and Swagger
-- | Get OpenApi
toOpenApi :: Server m -> OpenApi
-- add swagger to server
withSwagger :: SwaggerConfig m -> Server m -> Server m
-- create swagger server
swagger :: SwaggerConfig m -> m OpenApi -> Server m
-- | Print OpenApi schema
printOpenApi :: Server m -> IO ()
-- | Writes openapi schema to file
writeOpenApi :: FilePath -> Server m -> IO ()
The Swagger config:
-- | Swagger config
data SwaggerConfig m = SwaggerConfig
{ staticDir :: Path
-- ^ path to server swagger (default is "/swagger-ui")
, swaggerFile :: Path
-- ^ swagger file name (default is "swaggger.json")
, mapSchema :: OpenApi -> m OpenApi
-- ^ apply transformation to OpenApi schema on serving OpenApi schema.
-- it is useful to add additional info or set current date in the examples
-- or apply any real-time transformation.
}
instance (Applicative m) => Default (SwaggerConfig m) where
def =
SwaggerConfig
{ staticDir = "swagger-ui"
, swaggerFile = "swagger.json"
, mapSchema = pure
}
Set swagger title and description:
-- | Default info that is often added to OpenApi schema
data DefaultInfo = DefaultInfo
{ title :: Text
, description :: Text
, version :: Text
}
-- adds default info, use it in the mapSwagger field of SwaggerConfig record
addDefaultInfo :: DefaultInfo -> OpenApi -> OpenApi
Describe routes with swagger:
-- | Sets description of the route
setDescription :: Text -> Server m -> Server m
-- | Sets summary of the route
setSummary :: Text -> Server m -> Server m
-- | Adds OpenApi tag to the route
addTag :: Text -> Server m -> Server m
{-| Appends descriptiton for the inputs. It passes pairs for @(input-name, input-description)@.
special name request-body is dedicated to request body input
nd raw-input is dedicated to raw input
-}
describeInputs :: [(Text, Text)] -> Server m -> Server m