Search code examples
haskellscotty

Save state in memory [Haskell Server]


I am attempting to create a server that returns two different values from a route depending if a user has visited it before. I have the following code:

{-# LANGUAGE OverloadedStrings #-}
module Main where

import Web.Scotty

main = do
    putStrLn "Starting Server..."
    scotty 3000 $ do
        get "/" $ do
            -- if first time 
            text "hello!"
            -- if second time
            text "hello, again!"

I have two questions: 1. How can I check if a user has requested the route before? 2. Where and how can I persist application state?


Solution

  • You can use STM to keep a mutable variable in memory:

    import Control.Concurrent.STM.TVar
    
    main = do
        putStrLn "Starting Server..."
        state <- newTVarIO :: IO VisitorsData
        scotty 3000 $ do
            get "/" $ do
                visitorsData <- readTVarIO state
                -- if the visitor's ID/cookie is in visitorsData
                text "hello!"
                -- if new visitor, add them to visitorsData
                atomically $ modifyTVar state $ insertVisitor visitorId visitorsData
                -- if second time
                text "hello, again!"
    
    

    (If you expect to scale this to a complex server, you'll want to pass the TVar around in the form of a ReaderT pattern)