The DataKinds extension allows us to promote data constructors into type constructors, which also promotes their type constructors into kind constructors. To promote something up a level, we prefix the name with an apostrophe, or tick:
'
.
This segment from Basic Type Level Programming in Haskell.
The type of the web application is determined by the API type, through a type family named
Server
. (Type families are just functions that take types as input and return types.)
This segment from Serving an API.
In standard Haskell, operator symbols may only be used at the value level.The only exception to this is the function arrow, (->), which is a built-in type operator. GHC expands the role of operators with the TypeOperators extension, which makes it possible to use an operator as the name of a type.
This segment from Type Operators.
Aeson uses toEncoding
by default, so if the type has an instance, it will work.
There must be an instance of the FromHttpApiData
typeclass from http-api-data in order to parse directly to that type.
See Servant Docs - The truth behind JSON.
You can use blaze-html or lucid. For info about emitting them from servant, see Servant Docs - Case-studies: servant-blaze and servant-lucid.
Both
servant-blaze
andservant-lucid
let you useHTMLLucid
andHTMLBlaze
in any content-type list as long as you provide an instance of the appropriate class (ToMarkup
forblaze-html
,ToHtml
forlucid
).
type PersonAPI = "persons" :> Get '[JSON, HTMLLucid] [Person]
It appears that the first listed is default if no Accept
header is given. In this case JSON
.
By default, handlers run in the following Monad (infact, it is a newtype
of this type):
ExceptT ServerError IO
Errors thrown should be of the following type (from Servant.Server
):
data ServerError = ServerError
{ errHTTPCode :: Int
, errReasonPhrase :: String
, errBody :: ByteString -- lazy bytestring
, errHeaders :: [Header]
}
There are precompleted helpers such as err503
where you can override the part you want to change; usually errBody
.