Servant uses Servant.API.safeLink
to generate relative URLs, but I'm running into a problem that makes me think I am misunderstanding something basic either about how to use it or about how to define Servant APIs.
The minimal example I've constructed contains two endpoints. One is intended to be a "front door" endpoint at (relative URL) /foo
, and the other at /foo/1
:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
import Servant
data HTML
type Foo = "foo" :> (Foo0 :<|> Foo1)
type Foo0 = Get '[HTML] String
type Foo1 = "1" :> Get '[HTML] String
slFoo :: Link
slFoo = safeLink (Proxy :: Proxy Foo) (Proxy :: Proxy Foo1)
The definition of slFoo
above gives me the error
Could not deduce: IsElem' ("1" :> Get '[HTML] String) ("foo" :> (Foo0 :<|> Foo1))
...which is exactly the kind of error I get when safeLink is asked to produce a link which is not in the API defined by its first parameter. The error is similar when the second parameter to safeLink
is Proxy :: Foo0
instead.
I've tried many, many permutations of this and can't seem to figure it out by myself with the use of the documentation I've found. I'd appreciate some pointers that let me figure out where my misunderstanding(s) lie.
Foo1
doesn't include the leadingfoo
static path fragment, so when you ask servant to produce a link forFoo1
(within theFoo
API), it doesn't find an endpoint that matchesFoo1
exactly and complains. – Alp Mestanogullariservant-flatten
is appropriate here? Just like the client/server examples in those docs, you could pass a "flattened" version of yourFoo
API type assafeLink
's second argument, and the first argument could perhaps useNth
on the said flattened API type to hit the endpoint you want? – Alp MestanogullariapiProxy :: Proxy YourAPI
to whatever function you're using (serve
,client
,safeLink
, ...), you'd passflatten apiProxy
which has typeProxy (Flat YourAPI)
. You don't have to define an instance ofNth
, you just have to use it to get a proxy to the right endpoint.Nth <some number> <some flattened API type>
will give you an API type for the<some number> + 1
th endpoint.Nth 0
for the first,Nth 1
for the second, etc. Email me if this is not clear enough, I'm not a huge fan of SO for those matters. – Alp MestanogullariNth
doesn't seem to be used in public repositories. I'd be delighted to merge a patch that adds an example of usingNth
to its haddocks. =) Re: github search, I always look there first when I'm looking for examples of using some library/function/..., I definitely recommend it. – Alp Mestanogullari