如何使用 Snap Framework 在服务器端存储一些对象?

How do I store some object on server-side with Snap Framework?

这个问题已经在 2010 年提出,但我认为今天可能会有更好的答案。 基本上我需要存储某种对象并在每个请求中访问它,理想情况下我希望能够从请求中更改该对象(我想 MVar 或 IORef 可以做到这一点)。

snaplet 教程似乎表明这是可能的,但它主要解释了如何使用 snaplets(毕竟这就是该教程的目的),并没有真正解释这个 "App" 对象是如何工作的,或者甚至被存储。我不知道如何将它应用到我的案例中,我不需要 snaplets(我正在制作 API,所以我什至不需要 Heist)。

所以给定默认代码:

site :: Snap ()
site = do
  ifTop (writeBS "hello world") <|>
    route [ ("stuff/:param", someHandler) ] <|>
    dir "static" (serveDirectory ".")

如何将其更改为 "register" 我可以在 someHandler 中使用的某个对象? 2010 年的答案只是将它部分应用于每个处理程序,这会起作用,但 Snaplet 教程让我认为必须有更好的方法。

在 snaplet 教程的 "Working with State" 部分中,他们解释了如何使用本地状态。如果您查看上面名为 "Snaplet Overview" 的部分中的第二个代码片段,您可以看到他们在使用 Lens 为其初始化数据类型时如何设置状态。

不确定您对这些东西有多熟悉,但是 Lens 允许您访问(即 read/write/adjust)较大值内的数据片段。在这种情况下,服务器的整个状态表示为一个数据块(记录类型值),它在服务器启动时被初始化。

请注意:_companyName :: IORef B.ByteString <- 是您可以在示例中改变的一个状态,在 "Working with state" 部分中,这正是他们所做的。他们有一个示例,该示例采用 HTTP GET 或 POST 到 URL,并使用新的 "name" 参数 (POST) 和 returns 更新它新状态,或者如果它是 GET,它只是 returns 当前状态。