Haskell Servant:在ReqBody

时间:2016-09-06 07:53:19

标签: haskell servant

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

newtype Id = Id String
    deriving (Show, Eq, Ord, Generic)

instance ToJSON Id
instance FromJSON Id
instance FromHttpApiData Id where parseUrlPiece = Right . Id . Text.unpack

如此定义的仆人路线:

type SetEntryOrder = "entries" :> "order" :> ReqBody '[JSON] [Id] :> Post '[JSON] [Id]

我使用标题和请求正文向它发出请求,如下所示:

POST /entries/order HTTP/1.1
Host: localhost:9090
Connection: keep-alive
Content-Length: 199
Pragma: no-cache
Cache-Control: no-cache
Origin: http://localhost:9090
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
Content-Type: application/json
Accept: */*
Referer: http://localhost:9090/
Accept-Encoding: gzip, deflate
Accept-Language: en

["0pAWSlIHH38sApt0n101X2brrCkyYp","1aaaaaaaaaaaaaaaaaaaaaaaaaaaaa","2aaaaaaaaaaaaaaaaaaaaaaaaaaaaa","7T84N81O7T84N81O7T84N81Obeu4JU","vMfOGs2LvMfOGs2LvMfOGs2LzjlQIP","j1Ew8Ju7HzAIv2yH9ohcdl9Wm2o7qx"]

但我带着以下身体返回400(路线根本没有输入):

Error in $: expected record (:*:), encountered Array

我克隆了github仆人回购并且为了这个的各个部分而慌张但是什么都没发现。

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

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

> import Servant.API.ContentTypes (eitherDecodeLenient)
> eitherDecodeLenient "[\"hello\",\"hi\"]" :: Either String [Id]
Right [Id "hello",Id "hi"]

为我的Id类型定义自定义JSON处理程序,这样做不会有任何帮助:

instance ToJSON Id where
    toJSON (Id s) = String $ Text.pack s
instance FromJSON Id where
    parseJSON (String s) = return $ Id $ Text.unpack s
    parseJSON _ = empty

Sooo,有没有人知道为什么Servant试图解码我的Ids阵列并给我400而不是进入我的路线? :)

版本

堆叠LTS 6.15,意思是:

GHC 7.10.3,仆人0.7.1,仆人服务器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并使用它可以让我定位正确的路线。

有问题的重叠路线是:

type SetEntryOrder = HasSession :> "order" :> ReqBody '[JSON] [Id] :> Post '[JSON] [Id]

type AddEntry = HasSession :> ReqBody '[JSON] AddEntryInput :> Post '[JSON] Entry

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

更新2!

问题解决了!它实际上是因为我有重叠的路线,所以我的错!我为自己做了一些努力,因为重叠的路线几乎接受了任何输入(但我忘记了!)。交换路线固定它。

0 个答案:

没有答案