问题标签 [servant]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
157 浏览

haskell - 仆人总是在 ReaderT Monad 中给我一个初始值

我正在学习Servant并编写一个简单的服务。这是源代码:

似乎仆人defaultServices为每个请求提供了一个新的。我发送 POST 以创建服务(名称 =“文件”),但无法通过 GET 请求恢复服务。如何在服务端的请求之间共享数据?

0 投票
1 回答
1104 浏览

haskell - 如何在自定义服务处理程序中响应 HTTP 状态?

我创建了一个自定义仆人处理程序

但是我找不到在以下函数中向客户端响应 404-not-found 状态代码的方法:

如何发送404状态码???

0 投票
2 回答
234 浏览

haskell - 类型实例和虚拟类型

我遇到了一个奇怪的错误,我找不到修复它的方法。我正在使用servant,并且正在尝试构建一个通用的身份验证库(例如,默认情况下没有后端)。

代码如下:

Id是另一种类型的家庭。错误消息如下。

你知道我该如何修复这个代码吗?

0 投票
0 回答
60 浏览

servant - 我如何访问 :: BasicAuthCheck 用户内部的 :: Hasql.Pool.Pool ?

我通常通过作为参数传递:: Hasql.Pool.Poolserve函数作为run参数main :: IO ()

但是自从我开始计划使用:: BasicAuthCheck User身份验证后,我就开始需要:: Hasql.Pool.Pool里面:: BasicAuthCheck User包含:: BasicAuthData -> IO (BasicAuthResult User).

:: Hasql.Pool.Pool我目前的解决方法是在内部创建另一个:: BasicAuthData -> IO (BasicAuthResult User)并使用它来验证用户。

有没有比创建另一个连接池更优雅的方法?

0 投票
1 回答
923 浏览

haskell - 带有仆人的数据库支持的 REST API?

我在设置一个简单的概念证明服务 API 时遇到了问题。这是我的用户数据类型和我的 API 类型:

处理程序方法使用 postgresql-simple,如下所示:

已经省略了连接数据库和路由方法等样板代码。问题是,如果我发出 POST 请求,我想做的是创建一个新用户,所以我会提供 JSON:

但是然后我的程序在运行时失败了

这是有道理的,因为 API 指定了一个具有 id 字段的用户。但我不想在请求中传递一个虚假的 id(因为它们是由 postgres 顺序分配的),因为那很恶心。我也无法将 id 字段移出 User 数据类型,因为在向不同的端点发出 GET 请求时,由于模型数据库不匹配而导致 postgres-simple 失败(这很明显:通过 id 获取。不包括在上面)。我在这里做什么?编写自定义 FromJson 实例?我已经尝试将 Data.Aeson.TH 选项标志 omitNothingFields 设置为 True 并将 id 字段设置为 Maybe Int,但这也不起作用。任何意见,将不胜感激。

0 投票
0 回答
223 浏览

haskell - 使用servant-client生成动态请求

如果我在仆人 DSL 中描述了一些仆人的 API,例如:

type API = "some" :> QueryParam "a" Int :> QueryParam "b" Double:> Get '[JSON] Int

它有 HasClient 实例,所以我有一个客户端:

如果我要手动调用所有这些 API,那就太好了。但是,如果我需要从文本文件生成 HTTP 请求怎么办?

API我可以从使用(我自己的)类型类 生成简单的解析器,HasParser它解析来自文本文件的所有查询参数,如下所示:

但是如何将解析的结果与客户端的类型联系起来呢?

当然,我可以为每个API方法在值级别编写所有解析器,但是我想从API类型级别生成所有 thar 解析器,因此特别API是解析器应该生成一个函数:

Manager -> BaseUrl -> ClientM Int

甚至可能吗?

UPD。

好的,问题实际上包括两个:

1)如何生成生成通用客户端

2)如何生成解析器,实际上使用什么类型来保持解析结果。

(1)虽然很笨重,但很简单:

单例和二元组有两个实例,但很容易扩展所有可能维度的元组。

第二个问题还不清楚,我还不知道如何生成会产生不同维度元组的解析器。

UPD2。

使用嵌套元组的最小实现在这里: https ://gist.github.com/voidlizard/ef67a7ae486834d591d7b45c493bec1d

所以基本上这就是我想要的,但实现非常难看。是否有可能让它变得更好 - 使用一些 HLists 或 Vinyl 或其他东西来摆脱嵌套的元组?

UPD3 和结论。

好吧,好消息是很有可能的。我们可以定义和实现 HasParser 类型类,它定义了所有解析函数和类型或数据族来解析结果,以及 ConvertAPI 类型类,它将把 Servant 的客户端函数和解析结果转换为具有 type 的东西[Token] -> Manager -> BaseUrl -> ClientM a应该将a的类型包装成存在类型有一些复杂性,但它仍然是可能的。实现这一点仍然不完美,但这是另一个问题,如何实现具有现代特性(如类型级编程)的 API。

另一种方法是使用从servant 的API 定义生成的解析器,在Servant.Common.Req 上在值级别上构造HTTP 请求。更容易,但需要大量代码,并且以某种方式复制了 Servant 的 HasClient 实例。

坦率地说,我们都需要某种手册,如何使用现代类型级功能设计 API。

0 投票
1 回答
348 浏览

haskell - Use of `get` and `toSqlKey` in persistent

0 投票
0 回答
579 浏览

haskell - Haskell Servant:在 ReqBody 中使用自定义数据类型数组时出现 400 错误请求

所以,我有一个简单的 Id 类型:

一个仆人路线定义如下:

我使用以下标头和请求正文向它发出请求:

但是我得到了一个 400 并带有以下正文(根本没有输入路线):

我克隆了 githubservant repo 并搜索了它的各个部分,但一无所获。

值得注意的是,我还有很多其他路线都可以正常工作。

我想也许我的Id类型没有被正确解码(Aeson 预期的记录或其他东西),但我可以在 GHCI 中毫无问题地使用仆人在引擎盖下所做的同样的事情:

像这样为我的 Id 类型定义自定义 JSON 处理程序也无济于事:

Sooo,有没有人知道为什么 Servant 在试图解码我的 Id 数组并扔给我 400 而不是进入我的路线时卡住了?:)

版本

堆栈 LTS 6.15,这意味着:

GHC 7.10.3、servant 0.7.1、servant-server 0.7.1、aeson 0.11.2.1

(我也测试了servant-0.8.1但没有变化)

原始代码

https://github.com/jsdw/talklicker/tree/master/server(路由定义见Routes.hs,Id定义见Types.hs)

更新!

所以,问题似乎是仆人匹配了错误的路线,因为通过将正确的数据传递给我的/entries/orders路线(事实上,我似乎可以用任何字符串替换“订单”,并且尾部斜杠没有区别!),我实际上可以到达我的/entries路线。将另一个路由片段(例如:> "dadada")添加到 SetEntryOrder 并使用它可以让我定位正确的路由。

有问题的重叠路线是:

请注意,这两个都在我的 Routes.hs 文件顶部以“条目”为前缀。我还没有弄清楚为什么会这样,但这是一个开始!

更新2!

问题解决了!实际上是因为我的路线重叠,所以我的错!我为自己做了很多事情,因为重叠的路线几乎接受了任何输入(但我忘记了这一点!)。交换周围的路线固定它。

0 投票
1 回答
437 浏览

haskell - 如何向类型构造函数添加约束

考虑以下数据类型:

实际上,它是来自servant 的简化类型构造函数,然后在类型级API 中使用,如下所示:

出于我们的目的,我们可以将 API 缩减为

现在,对状态码的限制Nat过于宽松,允许定义一个不存在的 HTTP 状态码:

因此,问题是:有没有办法限制可以应用于Get类型构造函数的自然集合?

尝试了什么

为了清楚起见,我将省略代码示例中的所有编译指示和导入。

一种不同的statusCode

一种明显的解决方法是为状态代码定义一个单独的 ADT,并使用它来代替Nat使用数据类型提升。

但是,这是一个重大更改,需要升级主要版本并重写所有用户的定义。我怀疑限制代码的好处是否值得。

数据类型上下文

这个扩展允许对我们的类型变量有一个直接的约束

但它要求用户将约束添加到他们的所有声明中。再次,一个突破性的变化。此外,DatatypeContexts已弃用。

类型家庭

我们可以Get'使用类型族从下面的示例有条件地创建,但由于某种原因,声明类型别名会很高兴地编译。为了得到一个错误,我们需要构造一个这种类型的值,这也是一个突破性的变化。

0 投票
2 回答
1020 浏览

forms - 使用仆人处理常规表单帖子(application/x-www-form-urlencoded)

如何使用 Servant 处理常规形式的 POST?特别是,给定一个 HTML 表单,如

我怎么把东西串起来?