3

I'm trying to write a WAI middleware that puts some data in the request's vault, but it seems I'm missing something because I can't look it up later. Even the simplest middleware fail:

fooMW :: Middleware
fooMW app req sendResponse = do
  k <- Vault.newKey @Int
  let d = 42
      newVault = Vault.insert k d (vault req)
  app (req {vault = newVault}) $ \res -> sendResponse res

Which I then use like this:

main = scotty 3000 $ do
  middleware fooMW
  get "/foo" $ do
    k <- liftIO $ Vault.newKey @Int
    v <- vault <$> request
    let d = Vault.lookup k v
    liftIO $ print d
    json $ object ["foo" .= ("bar" :: Text)]

When doing http :3000/foo I expect the server to print Just 42 but in prints Nothing, suggesting that something's wrong in fooMW. I guess I'm missing something crucial about how to write middlewares, or how to use vault, but what?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Magnus
  • 4,644
  • 1
  • 33
  • 49
  • 1
    The code seems to assume that the two invocations of `Vault.newKey` return the *same* key, but I'm not sure that's the case. Perhaps you could create the key once, in `main`, and then share it between the middleware and the handler. – danidiaz Jul 07 '20 at 12:37
  • Yes, that's indeed the case. Thanks for clearing that up. – Magnus Jul 07 '20 at 15:52

1 Answers1

2

Calling Vault.newKey produces a different key every time, so it should be called once and shared instead of being called every time the key is used. Thanks @danidiaz

Magnus
  • 4,644
  • 1
  • 33
  • 49