haskell-servant / haskell-servant/servant

How to Capture with .ext suffix?

Open
#1,647 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
Haskell
Stars
2k
Forks
427
Avg merge
2d 23h
Merged PRs (30d)
5

Description

Hi, I have an API that I'm querying which in simplest form looks like:

`/int.json`

The type I tried is:

`type publicAPI = Capture "index" Int :> ".json" :> Get '[JSON] PublicData`

But it constructs a query with an additional slash:

`/int/.json`

Is there a way to remove that slash?

I'm not too good with higher haskell and tried to make a new combinator building off of the existing Capture but it doesn't compile:

```
data CaptureWithSuffix (sym1 :: Symbol) (a :: *) (sym2 :: Symbol)
deriving (Typeable)
````

```
type publicAPI = CaptureWithSuffix "index" Int ".json" :> Get '[JSON] PublicData
```

```
suffixToPath :: Builder -> Request -> Request -- TODO suffix
suffixToPath p req
= req { requestPath = requestPath req <> "/" <> p }

instance (KnownSymbol capture, KnownSymbol suffix, ToHttpApiData a, HasClient m api)
=> HasClient m (CaptureWithSuffix capture a suffix :> api) where

type Client m (CaptureWithSuffix capture a suffix :> api) =
a -> Client m api

clientWithRoute pm Proxy req val = -- TODO pass in suffix
clientWithRoute pm (Proxy :: Proxy api)
(suffixToPath p req)

where p = toEncodedUrlPiece val

hoistClientMonad pm _ f cl = \a ->
hoistClientMonad pm (Proxy :: Proxy api) f (cl a)
```

The error looks like like somewhere is missing an argument, but I don't understand it:

```
src/ServantClient.hs:40:3: error:
• Couldn't match type ‘Client m api0’ with ‘Client m api’
Expected type: Client m (CaptureWithSuffix capture a suffix :> api)
Actual type: a -> Client m api0
NB: ‘Client’ is a non-injective type family
The type variable ‘api0’ is ambiguous
• The equation(s) for ‘clientWithRoute’ have four arguments,
but its type ‘Proxy m
-> Proxy (CaptureWithSuffix capture a suffix :> api)
-> Request
-> Client m (CaptureWithSuffix capture a suffix :> api)’
has only three
In the instance declaration for
‘HasClient m (CaptureWithSuffix capture a suffix :> api)’
src/ServantClient.hs:46:32: error:
• Couldn't match type ‘Client mon' api1’ with ‘Client mon' api’
Expected type: Client
mon' (CaptureWithSuffix capture a suffix :> api)
Actual type: a -> Client mon' api1
NB: ‘Client’ is a non-injective type family
The type variable ‘api1’ is ambiguous
• The lambda expression ‘\ a
-> hoistClientMonad pm (Proxy :: Proxy api) f (cl a)’
has one argument,
but its type ‘Client
mon' (CaptureWithSuffix capture a suffix :> api)’
has none
In the expression:
\ a -> hoistClientMonad pm (Proxy :: Proxy api) f (cl a)
In an equation for ‘hoistClientMonad’:
hoistClientMonad pm _ f cl
= \ a -> hoistClientMonad pm (Proxy :: Proxy api) f (cl a)
```

How would I write this if this the way to go or is there a better way?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.