Haskell 仆人:从 API 构造 URL
Haskell Servant: Construct URL from API
假设我们有这个简单的 API:
type FooAPI
= "foo"
:> QueryParam "age" Int
:> Get '[PlainText] Text
有没有一种方法可以将 link 类型级 servant
的 API 的 API 生成 URL 的函数?喜欢
someMagicFunction :: Proxy api -> SomeTypeFamily api
someMagicFunction = ?
generateURL :: Maybe Int -> Text
generateURL = someMagicFunction (Proxy @FooAPI)
>>> generateURL (Just 42)
"https://somehost/foo?age=42"
>>> generateURL Nothing
"https://somehost/foo"
我想提高 URL 代的类型安全性,所以如果我向 FooAPI
添加一些新参数,它将立即出现在 generateURL
的类型和我的代码中如果不编辑 generateURL
.
的调用将无法编译
我知道 servant-client
库,我知道 client
函数有点相似,但我不知道如何在我的案例中使用这个库。
我会说 Servant.Links
正是您要找的。
特别是,在您的情况下,我会使用 allLinks
生成对应于包含路径和查询参数的 URL 片段的 Link
:
>>> linkURI $ allLinks (Proxy @FooAPI) Nothing
foo
>>> linkURI $ allLinks (Proxy @FooAPI) (Just 18)
foo?age=18
然后我会将生成的 Link
转换为 URI
,我会在其中指定所需的方案和主机名。这是一个完整的工作模块:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
import Data.Proxy
import Data.Text (Text)
import Network.URI
import Servant.API
import Servant.Links
type FooAPI
= "foo"
:> QueryParam "age" Int
:> Get '[PlainText] Text
generateURL :: Maybe Int -> String
generateURL age = show uri
{ uriScheme = "https:"
, uriAuthority = Just nullURIAuth
{ uriRegName = "somehost" }
, uriPath = "/" <> uriPath uri
}
where
uri = linkURI link
link = allLinks (Proxy @FooAPI) age
及示范:
>>> generateURL (Just 42)
"https://somehost/foo?age=42"
>>> generateURL Nothing
"https://somehost/foo"
假设我们有这个简单的 API:
type FooAPI
= "foo"
:> QueryParam "age" Int
:> Get '[PlainText] Text
有没有一种方法可以将 link 类型级 servant
的 API 的 API 生成 URL 的函数?喜欢
someMagicFunction :: Proxy api -> SomeTypeFamily api
someMagicFunction = ?
generateURL :: Maybe Int -> Text
generateURL = someMagicFunction (Proxy @FooAPI)
>>> generateURL (Just 42)
"https://somehost/foo?age=42"
>>> generateURL Nothing
"https://somehost/foo"
我想提高 URL 代的类型安全性,所以如果我向 FooAPI
添加一些新参数,它将立即出现在 generateURL
的类型和我的代码中如果不编辑 generateURL
.
我知道 servant-client
库,我知道 client
函数有点相似,但我不知道如何在我的案例中使用这个库。
我会说 Servant.Links
正是您要找的。
特别是,在您的情况下,我会使用 allLinks
生成对应于包含路径和查询参数的 URL 片段的 Link
:
>>> linkURI $ allLinks (Proxy @FooAPI) Nothing
foo
>>> linkURI $ allLinks (Proxy @FooAPI) (Just 18)
foo?age=18
然后我会将生成的 Link
转换为 URI
,我会在其中指定所需的方案和主机名。这是一个完整的工作模块:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
import Data.Proxy
import Data.Text (Text)
import Network.URI
import Servant.API
import Servant.Links
type FooAPI
= "foo"
:> QueryParam "age" Int
:> Get '[PlainText] Text
generateURL :: Maybe Int -> String
generateURL age = show uri
{ uriScheme = "https:"
, uriAuthority = Just nullURIAuth
{ uriRegName = "somehost" }
, uriPath = "/" <> uriPath uri
}
where
uri = linkURI link
link = allLinks (Proxy @FooAPI) age
及示范:
>>> generateURL (Just 42)
"https://somehost/foo?age=42"
>>> generateURL Nothing
"https://somehost/foo"