haskell 如何访问中间件中的响应状态?

kq0g1dla  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(167)

我有一个WAI中间件:

myMiddleware :: WAI.Middleware
myMiddleware prevApp req respond = do
  resp :: ResponseReceived <- prevApp req respond  --  SIC!
  let path = T.intercalate "/" $ WAI.pathInfo req
      method = WAI.requestMethod req
      -- Q: how to get the response's status    <----  ???
      --respStatus = WAI.responseStatus resp    <----  ???
  pure resp

在这里我想得到一个响应的状态(它是404,或者200,或者其他什么)。但是如果它不是Response more而是ResponseReceived,该怎么做呢?我只有一个想法,比如说,创建IORef并将其传递给我的函数:

-- an illustration of the idea:
...
  xxx <- newIORef []
  let myRespond resp = do
        atomicWriteIORef' xxx [1,2]
        r <- respond resp
        pure r
  resp <- prevApp req myRespond
...

但1)我不知道这是不是最简单最典型的解决方案; 2)newIORef的轻量级程度如何?是否可以在每次对应用程序的请求时创建它?
我以前多次触及这个问题,主要的问题是:如何访问中间件中的响应?2最终响应,我的意思是如果应用程序以404回答,那么能够访问中间件中的状态404。

ukqbszuj

ukqbszuj1#

一般的想法是编写一个中间件,看起来像这样:

mid :: Middleware
mid app req respond = app req respond'
  where respond' res = do
          let status = responseStatus res
          putStrLn $ "status=" ++ show status
          respond res

也就是说,根本不需要访问ResponseReceived--它是一种“sentinel”值,不包含任何可以访问的信息。相反,在继续原始的respond调用之前,用一个访问传出响应的回调覆盖传递给应用程序的respond'回调。
现在,您 * 使用 * status值的方式取决于您想要实现的目标。(或几千个)。然而,它看起来不会有很大的帮助。一旦你创建了它,你会把它传递给什么函数呢?如果你如果您能够为每个请求向函数传递一个新的IORef,为什么不直接传递status呢?

相关问题