Reputation: 14887
The project I'm working on involve calling to CloudFlare API. I've already define the API using Servant (client) and I'm able to make a client out of it. However, CloudFlare API requires authentication headers, so all of my API types end up with duplication. Is there any way to get rid of those at the type level? I'm happy with the client derived functions require those parameters.
Example code:
type ListZones = "zones"
:> Header "X-Auth-Email" Text
:> Header "X-Auth-Key" Text
:> Get '[JSON] (Result [Zone])
type ListRecords = "zones"
:> Header "X-Auth-Email" Text
:> Header "X-Auth-Key" Text
:> Capture "zone_uuid" Text
:> "dns_records"
:> Get '[JSON] (Result [Record])
type CreateRecord = "zones"
:> Header "X-Auth-Email" Text
:> Header "X-Auth-Key" Text
:> Capture "zone_uuid" Text
:> "dns_records"
:> ReqBody '[JSON] Record
:> Post '[JSON] (Result Record)
type UpdateRecord = "zones"
:> Header "X-Auth-Email" Text
:> Header "X-Auth-Key" Text
:> Capture "zone_uuid" Text
:> "dns_records"
:> Capture "record_uuid" Text
:> ReqBody '[JSON] Record
:> Patch '[JSON] (Result Record)
Upvotes: 1
Views: 152
Reputation: 1302
I believe you'll want to pull the common bits out in a similar fashion to the one outlined here: http://www.parsonsmatt.org/2018/03/14/servant_route_smooshing.html
He goes from:
type Api
= "player"
:> Capture "playerId" Int
:> "x"
:> Get '[JSON] Int
:<|> "player"
:> Capture "playerId" Int
:> "y"
:> Get '[JSON] Int
to
type Api'
= "player"
:> Capture "playerId" Int
:> ( "y" :> Get '[JSON] Int
:<|> "x" :> Get '[JSON] Int
)
which is simpler than what you need to do, but shows how to get started.
Hope that helps.
Upvotes: 1