如何将HTTP请求参数传递给quickQuery?

时间:2018-02-17 20:12:47

标签: haskell happstack hdbc

我正在使用Happstack从HTTP请求接收一些参数,然后将这些参数传递给一个函数,该函数将从数据库中检索数据并在HTTP响应中返回此数据,如下所示:

myFunc :: IO String
myFunc = do r <- look "personId"
            conn <- connectODBC "... my connection string ...";
            vals <- quickQuery conn ("SELECT Name FROM Person where Id = ?") [(toSql r)];
            return (processData vals)

handlers :: ServerPartT IO Response
handlers = do
       x <- liftIO (myFunc);
       decodeBody (defaultBodyPolicy "/tmp/" 0 1000 1000)
       msum [ 
              dir "getData" $ ok $ toResponse x
            , ... other handlers ...
            ]

mainFunc = simpleHTTP nullConf handlers

但是当我构建上面的代码时,我收到以下错误:

  

使用`look'不会产生(HasRqData IO)的实例   在'do'块的stmt中:r&lt; - look“personId”

在阅读有关类似问题的问题后(​​例如this one),我认为我必须在某处包含HasRqData约束,但我无法了解地点和方式。

1 个答案:

答案 0 :(得分:1)

正如您可能已经猜到的那样,monad也是一个问题。 happstackHasRqData等)中有handful个,因此您可能会认为这是一个复杂的案例。

让我们从无辜的 look函数开始。

look :: (Functor m, Monad m, HasRqData m) => String -> m String

实际上,存在一个非平凡的约束HasRqData。让我们问问自己:what monads HaveRqData? (碰巧IO没有!)

class HasRqData m where
...

Instances
    HasRqData RqData         
    (MonadIO m, MonadPlus m) => HasRqData (ServerPartT m)
    ...

其他实例是前两个实例的衍生物,因此,看起来我们必须首先考虑这两个选项。

  • RqData效果有限 - 您只能look及其衍生物,从手头的请求中提取信息。因为我们还希望有其他效果 - 例如查询数据库 - 这对我们来说还不够。
  • ServerPartT m是同一old friend of oursServerPart ≡ ServerPartT IO的一般形式。碰巧它也是HasRqData。这不是巧合,而是happstack设计的含义 - 看起来作者的意思是我们在任何地方使用这个单一的monad,除非我们需要特定的粒度。所以,让我们试一试。

myFunc :: ServerPart String
myFunc = do r <- look "personId"
            return undefined

编译。

现在,我们甚至不需要在myFunc中举起handlers - 我们previous predicament解决了问题。我们需要通过我们之前讨论过的jar logic提升对数据库的访问权。

我相信你可以自己计算细节。在任何情况下,让我知道它是如何工作的!