如何为服务方定义服务器发送事件(SSE)端点.文档似乎不包括这种情况.
如果Servant不是为实时用例而设计的,哪个Haskell服务器框架支持SSE?
如何使用Servant处理常规表单POST?特别是,给定HTML格式,例如
<form action="/check" method="post">
Solution:
<input name="code" type="text">
<input type="submit">
</form>
Run Code Online (Sandbox Code Playgroud)
和
data CheckResult = Correct | Wrong
instance ToHtml CheckResult
...
checkCode :: Text -> Handler CheckResult
checkCode code = if code == "secret" then Correct else Wrong
Run Code Online (Sandbox Code Playgroud)
如何将东西串在一起?
我在Haskell servant中有一个hello world应用程序,这是它的一部分:
type API =
"my_items" :> Get '[JSON] [MyItem]
:<|> "my_items" :> Capture "id" Int :> Get '[JSON] MyItem
-- ...................
Run Code Online (Sandbox Code Playgroud)
并且网址是:
localhost/my_items
localhost/my_items/123
Run Code Online (Sandbox Code Playgroud)
如何为现有网址和我将创建的其他网址添加前缀:
localhost/api/v1/my_items
localhost/api/v1/my_items/123
localhost/api/v1/.....
Run Code Online (Sandbox Code Playgroud)
?
我有一个带有 REST API 的简单仆人应用程序:
type API = "items" :> Get '[JSON] [MyData]
app :: Application
app = serve api server
api :: Proxy API
api = Proxy
server :: Server API
server = getItems
getItems :: ExceptT ServantErr IO [MyData]
getItems = ......
startApp :: IO ()
startApp = run 1234 app
Run Code Online (Sandbox Code Playgroud)
如何根据条件访问 http 标头并返回特定响应(例如 http403)?
我有一个简单的hello world Servant应用程序。我需要向其中添加一些静态或动态html页面。我怎样才能做到这一点?在文档中没有提到。注意:我不想在Haskell代码中创建html布局,而是希望Haskell显示已经创建的html页面。
更新:
我该如何结合:
type MyApi = "/" :> Raw
server :: Server MyApi
server = serveDirectory "static/" -- index.html, about.html
Run Code Online (Sandbox Code Playgroud)
我已经拥有的:
type API =
"api" :> "items" :> Get '[JSON] [MyData] :<|>
"api" :> "items" :> Capture "id" Int :> Get '[JSON] MyData
app :: Application
app = serve api server
api :: Proxy API
api = Proxy
server :: Server API
server = getItems :<|> getItem
startApp :: IO ()
startApp = run 1234 app
Run Code Online (Sandbox Code Playgroud)
UPDATE2:
工作方式: …
我正在使用自定义monad(带阅读器)轻松地将数据库(如DB池)传递给我的处理程序(在使用自定义monad之前,我曾将连接作为fn参数传递).
这就是我定义自定义monad的方法:
newtype Controller a = Controller
{ runController :: ReaderT ServerEnvironment Handler a
} deriving ( Functor, Applicative, Monad, MonadReader ServerEnvironment,
MonadError ServantErr, MonadIO )
Run Code Online (Sandbox Code Playgroud)
这ServerEnvironment只是我用来携带数据的自定义数据类型.
问题是,对于我,AuthHandler我必须具体使用以下功能:
r -> Handler usr
Run Code Online (Sandbox Code Playgroud)
作为身份验证处理程序,我不能使用我的自定义处理程序,它将是:
r -> Controller usr
Run Code Online (Sandbox Code Playgroud)
而且我也无法传递我,ConnectionPool因为签名不能是:
ConnPool -> r -> Handler usr
Run Code Online (Sandbox Code Playgroud)
那么,如何在不使用全局IO状态的情况下将额外数据传递给servant中的身份验证处理程序?
我想获得与我的处理程序相对应的当前路线。这是我的服务器模型,仅供参考:
type ServerAPI =
"route01" :> Get '[HTML] Text
:<|> "route02" :> "subroute" :> Get '[HTML] Text
:<|> "route03" :> Get '[HTML] Text
Run Code Online (Sandbox Code Playgroud)
这里有一些处理程序:
route1and2Handler :: Handler Text
route1and2Handler = do
route <- getCurrentRoute
addVisitCountForRouteToDatabaseOrSomethingOfThatSort...
return template
route3Handler :: Handler Text
route3Handler = return "Hello, I'm route 03"
Run Code Online (Sandbox Code Playgroud)
还有我的服务器:
server :: Server ServerAPI
server = route1and2Handler :<|> route1and2Handler :<|> route3Handler
Run Code Online (Sandbox Code Playgroud)
所以,基本上我route1and2Handler应该有一些方法来获得当前路线。我已经尝试将请求对象放入我的处理程序并通过实现这样的HasServer实例从中提取 url :
data FullRequest
instance HasServer a => HasServer (FullRequest :> a) where
type Server …Run Code Online (Sandbox Code Playgroud) 假设我们有这个简单的 API:
type FooAPI
= "foo"
:> QueryParam "age" Int
:> Get '[PlainText] Text
Run Code Online (Sandbox Code Playgroud)
有没有办法将 type-levelservant的 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"
Run Code Online (Sandbox Code Playgroud)
我想提高 URL 生成的类型安全性,因此如果我向其中添加一些新参数,FooAPI它将立即出现在 的类型中generateURL,并且如果不编辑 的调用,我的代码将无法编译generateURL。
我知道servant-client库,并且我知道该client函数的功能有些类似,但我不知道如何在我的情况下使用这个库。
我有一种代表持久记录的类型。我想要一个非常相似的类型来表示应该发布以创建新记录的数据。
这是完整的类型:
data Record = Reading
{ id: UUID
, value: String
...
}
Run Code Online (Sandbox Code Playgroud)
“新”类型与减去“id”相同,该“id”将由数据库自动生成。我如何定义这个类型?我正在使用servant 来定义API。
我当前的策略是在类型和所有字段前加上“new”前缀,这有效,但对于多字段模型来说是多余的。我还看到了嵌套策略,其中我有一个共同的共享类型。我也考虑过将 id 设为可选,但我真的不想发布它。
我正在尝试使用telegram-api构建Telegram机器人.到目前为止,我还没有遇到任何问题,因为我可以阅读测试以了解事情是如何工作的,但是在使用Servant构建webhook端点时我遇到了很多麻烦.总的想法是,当我Update从webhook 收到一个,我发回一个回复.
问题在于我的postWebhook代码,它希望收到一个Message但是收到一个IO Message.我认为这是因为Servant不希望我在该函数内部发出请求,因为我确实应该有类型EitherT ServantError IO (IO Message)(部分应用BotHandler)EitherT ServantError IO Message.
我还在学习Haskell,但我知道我不得不从IO monad中获取消息?更新BotAPI返回a Post '[JSON] (IO Message)给我这个:No instance for (Foldable IO) arising from a use of ‘serve’,这超出了我的初学者的知识,我可以看到摆弄类型只是将相同的问题移动到代码的不同部分.我只是不知道如何解决它.
以下是删除了敏感字符串的代码:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeOperators #-}
module Main where
import Control.Monad
import Control.Monad.Trans.Either
import Data.Proxy
import Data.Text (Text, pack) …Run Code Online (Sandbox Code Playgroud)