简体   繁体   English

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

[英]How to pass HTTP request parameter to quickQuery?

I'm using Happstack to receive some parameters from an HTTP request then pass these parameters to a function that will retrieve data from the database and return this data in the HTTP response as follow:我正在使用 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

But when I build the above code I get the following error:但是当我构建上面的代码时,我收到以下错误:

No instance for (HasRqData IO) arising from a use of `look' In a stmt of a 'do' block: r <- look "personId"没有因使用“look”而产生的 (HasRqData IO) 实例在“do”块的 stmt 中:r <-look "personId"

After reading questions on similar issues (like this one ) I think I have to include HasRqData constraint somewhere, but I couldn't learn where and how.在阅读了关于类似问题的问题(比如这个)后,我想我必须在某处包含HasRqData约束,但我无法了解在哪里以及如何。

As you may have guessed, this is too an issue with monads.您可能已经猜到了,这也是 monad 的问题。 There are a handful of them in happstack ( HasRqData , among others), so you may well consider it a complicated case. happstack中有一些HasRqData等),因此您可能会认为这是一个复杂的案例。

Let us begin with the innocent-looking look function.让我们从look无辜的look功能开始。

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

Indeed, there is a non-trivial constraint HasRqData .事实上,有一个重要的约束HasRqData Let us ask ourselves: what monads HaveRqData ?让我们问问自己: 什么 monads HaveRqData (It so happens that IO has not!) (碰巧IO没有!)

class HasRqData m where
...

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

The other instances are derivative of these first two, so, it looks like we have to consider these two options first.其他实例是前两个的派生类,因此,看起来我们必须首先考虑这两个选项。

  • The RqData has limited effects — you can only do look and its derivatives, extracting information from the request at hand. RqData效果有限——你只能做look和它的衍生,从手头的请求中提取信息。 As we want to also have other effects — querying the database, for one, — this is not enough for us.由于我们还想要其他效果——例如查询数据库——这对我们来说是不够的。
  • The ServerPartT m is the general form of the same old friend of ours , ServerPart ≡ ServerPartT IO . ServerPartT m我们的老朋友ServerPart ≡ ServerPartT IO的一般形式。 It happens that it also HasRqData .碰巧它也有HasRqData This is not a coincidence, but rather an implication of the design of happstack — looks like the authors meant us to use this single monad everywhere, unless we need particular granularity.这不是巧合,而是happstack设计的happstack ——看起来作者的意思是我们在任何地方都使用这个单一的 monad,除非我们需要特定的粒度。 So, let's give it a try.所以,让我们试一试。

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

This compiles.这编译。

Now, we don't even need to lift myFunc in handlers — our previous predicament solved itself.现在,我们甚至不需要在handlers提升myFunc - 我们之前的困境自己解决了。 We will need to lift our access to the database though, by the same jar logic we discussed before.不过,我们将需要通过我们之前讨论的相同jar 逻辑来提升对数据库的访问权限。

I believe you can figure the details by yourself.我相信你可以自己弄清楚细节。 In any case, let me know how it works out!无论如何,让我知道它是如何工作的!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM