tungd
tungd

Reputation: 14887

Reduce duplication in Haskell Servant

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

Answers (1)

tylerweir
tylerweir

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

Related Questions