HATEOAS support for servant.
This is not affiliated with the official servant
maintainers.
Currently in infant state. Final goal is something similar to what has been proposed here.
Define an instance for class ToResource api res a
where api
is the type of your Servant-Api within which the resty representation
of your datatype a
lives and res
is the resource-representation to create.
When providing some extra information with an instance for Related a
there are stock instances which derive the links
based on the relations in your instance.
data User = User { usrId :: Int, addressId :: Int, income :: Double }
deriving stock (Generic, Show, Eq, Ord)
deriving anyclass ToJSON
data Address = Address { addrId :: Int, street :: String, number :: Int}
deriving stock (Generic, Show, Eq, Ord)
deriving anyclass ToJSON
type CompleteApi = AddressApi :<|> UserApi
type AddressApi = AddressGetOne
type AddressGetOne = "address" :> Capture "id" Int :> Get '[HAL JSON] (HALResource Address)
type UserApi = UserGetOne :<|> UserGetAll
type UserGetOne = "user" :> Capture "id" Int :> Get '[HAL JSON] (HALResource User)
type UserGetAll = "user" :> Get '[Collection JSON] (CollectionResource User)
instance Related User where
type IdSelName User = "usrId"
type GetOneApi User = UserGetOne
type CollectionName User = "users"
type Relations User =
'[ 'HRel "address" "addressId" AddressGetOne
]
>>> mimeRender (Proxy @(HAL JSON)) $ toResource @CompleteApi @HALResource $ User 1 42 100000
{
"_links": {
"address": {
"href": "address/42"
},
"self": {
"href": "user/1"
}
},
"addressId": 42,
"income": 100000,
"usrId": 1
}
- Deriving simple links for self and relations
- Deriving more complex links...?
-
Type-level rewriting of APIs like
CompleteAPI
to make API HATEOAS-compliant
-
application/hal+json
-
application/collection+json
-
application/hal-forms+json
soon - Others: Maybe
Client usage with MimeUnrender
is not yet supported.
Contributions, critics and bug reports are welcome!
Please feel free to contact me through GitHub.