[英]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.其他实例是前两个的派生类,因此,看起来我们必须首先考虑这两个选项。
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.由于我们还想要其他效果——例如查询数据库——这对我们来说是不够的。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.