haskell-servant / haskell-servant/servant
Specialized `fromServant` for clients
- Dominant language
- Haskell
- Stars
- 2k
- Forks
- 427
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 5
Description
When dealing with a generic and nested API, like this - admittedly simplified - one:
```hs
data API route = API
{
foo :: route :- "foo" :> ToServantApi FooAPI
} deriving (Generic)
data FooAPI route = FooAPI
{
bar :: route :- "bar" :> ToServantApi BarAPI
} deriving (Generic)
data BarAPI route = BarAPI
{
baz :: route :- "baz" :> Get '[JSON] String
} deriving (Generic)
```
Composition for client callers is tricky. One can of course write separated functions, like this:
```hs
apiClient :: API (AsClientT ClientM)
apiClient = genericClient
fooClient :: FooAPI (AsClientT ClientM)
fooClient = fromServant $ foo apiClient
barClient :: BarAPI (AsClientT ClientM)
barClient = fromServant $ bar apiClient
```
Of course, in this silly example, it's acceptable boiler-plate, but picture a much bigger and deeper API. We quickly realized it was not possible to do something that would have felt natural, like:
```hs
quickBarClient :: BarAPI (AsClientT ClientM)
quickBarClient = fromServant . bar . fromServant . foo $ genericClient
```
I'm not quite sure I understand why exactly, but since the compiler kept getting lost with ambiguous types over the `route` parameter, we've tried this simple enough function:
```
fromServant' :: (m ~ AsClientT n) => GenericServant routes m
=> ToServant routes m -> routes m
fromServant' = fromServant
```
And lo and behold, it lets us compose thus:
```hs
quickBarClient :: BarAPI (AsClientT ClientM)
quickBarClient = fromServant' . bar . fromServant' . foo $ genericClient
```
This leads me to two questions:
1°) Is there such a function already somewhere in the codebase ? Because I feel like I'm missing something and not using your excellent library properly.
2°) If the answer to the previous question was no, what about adding such a specialized function (maybe with a shorter name) to the Servant.Client.Generic module to guide users towards a workable composition ?
Contributor guide
Assessment
This issue has not been assessed yet.