Post and get variable using yesod server

var express = require('express')
var app = express()
var store = undefined

app.post("/", function(req, res){
  store = req.body
})

app.get("/", function(req, res){
  res.send(store)
} 
app.listen(some_port_num)

      

This is a simple nodejs / express server application that stores the HTTP request body in a global variable and sends the same variable as the receive request response.

How can I write this code in yesod / haskell. I don't know how to use the global / module variables in the haskell / yesod scope. And is there any other way to exchange variables between two functions in haskell?

+3


source to share


1 answer


Using global constants is trivial in Haskell: you just write foo = bla

somewhere (preferably signed foo :: FooType

). foo

can then be used anywhere in your module (or even outside if you export it).

OTOH global variables are actually not possible in Haskell. For the most part, this is a good thing, because the global state tends to lead to a lot of mistakes. Often when programmers think about global variables, it turns out that the global constants will be fine, otherwise the state variable is better rewritten as explicit parameters.

Sometimes you tend to want state variables. Specifically, Yesod has a place where you can store them in different ways: Yesod. It is a data structure that your web application has as its footer. For example, you might have

data YourYesod = YourYesod {
      ...
      , reqStore :: IORef RequestBody   -- IORef basically means, it variable
                                        -- in the imperative sense.
      ...
      }

mkYesod "YourYesod" [parseRoutes| ... |]

      

Yesod can be accessed from anywhere in monads Handler

, etc., for example. in



getHomeR :: Handler Html
getHomeR = do
    ...
    yourYesod <- getYesod           -- gain "access" to the Yesod
    storeS <- liftIO $ readIORef (reqStore yourYesod)  -- look up the variable state
    ...
    liftIO $ writeIORef (reqStore yourYesod) newStoreS -- write new state
    ...

      

At the beginning of the program, reqStore

you will need to initialize, for example,

main :: IO ()
main = do
   ...
   initReqStore = newIORef emptyRequest
   ...
   warp 3000 $ YourYesod ... initReqStore ...

      

Before doing this, consider whether the variable really store

needs to be global. Yesod is pretty much the most global scale you have for this kind of thing; it also means the danger of such common mistakes as in procedural languages. If a variable is only used in one handler, you can simply inject it locally, like

               do
                 ...
                 store <- newIORef emptyRequest
                 appPost "/" $ \req res -> do
                       liftIO $ writeIORef store $ body req
                 appGet "/" $ \req res -> do
                       storedReq <- liftIO $ readIORef store
                       send res storedReq

      

+6


source







All Articles