I am writing a web server using Scotty. The server should have a login route that once user logs in, a token is dispatched and recorded in the server. Obviously the recorded tokens should be in a global state (not using Redis kind of thing because the server is run on single machine and has small view counts).
Now I know the Scotty examples have shown how to define and access global states in routes, but I can't find out how to do the same thing for middlewares.
I tried using the same way from the official example but neither the middleware function nor the app function has a WebM monad context so I can't really do this:
app = do
tokensList <- webM $ gets tokens
middleware $ authMiddleware tokensList
That "official example" isn't so great. I mean, it's a good example of using a custom monad, but it's a lousy example of how to provide global state. You don't need the custom monad at all. You just need the
TVar.Ultimately, all you need to do is create the
newTVarinmain, and then pass it to theappfunction to construct the application and middleware, which can access theTVardirectly with liftedIOoperations in the application andIOoperations in the middleware. It'll look something like the following:To illustrate, here's a rewrite of that official example without the monad that operates on the
TVardirectly in the handler. (No middleware yet, but see the example further below.)and here's a version that uses middleware to count page accesses and queries and resets the value from the handlers, all directly through the
TVarwithout requiring any custom monad: