happs-tutorial-0.5.0: templates/mainfunction.st
<h3>Where it all begins: the function main</h3>
<p>Have a look at the <a href="/src/Main.hs">Main.hs</a> module which is at the core of this web application.</p>
<p>In particular, notice the line
<p>smartserver (Conf p Nothing) "happs-tutorial" (controller allowStressTests) stateProxy
<p>This is a library function, which can be looked up via the ghci info directive (or i for short):
<br>
<br>*Main> :i smartserver
<br>smartserver ::
<br> (Methods st, Component st, ToMessage a) =>
<br> Conf -> String -> [ServerPartT IO a] -> Proxy st -> IO ()
<br> -- Defined in HAppS.Server.Helpers
<p>Each of these arguments is important enough to say something brief about.
<p>In this case, the configuration argument just specifies the port the server runs on.
<p>The second string argument controls where serialized app state will
be stored: in this case, under "_local/happs-tutorial". This is mainly for convenience, so the state
directory is the same whether we are running in ghci or ghc. (HAppS out of the box just looks
at the executable name, which in the case of ghci is something weird.)
<p>The third argument tells HAppS what to use as a controller, in the MVC sense.
Basically, how to handle http requests.
<p>The fourth argument tells happs what data structure to use for application state.
We'll cover about the HAppS state system in depth, but later.</p>
<p>To learn more about what the controller function is doing,
, open this file in ghci: cd src; ghci Main.hs and have a look at these functions using ghci :info .</p>
<p>
<br>*Main> :i controller
<br>controller :: Bool -> [ServerPartT IO Response]
<br> -- Defined at <a href="/src/Controller.hs">Controller.hs</a>...
<br>
<br>*Main> :i ServerPartT
<br>newtype ServerPartT m a = ServerPartT {unServerPartT :: Request -> WebT m a}
<br> -- Defined in HAppS.Server.SimpleHTTP
<br>instance [overlap ok] (Monad m) => Monad (ServerPartT m)
<br> -- Defined in HAppS.Server.SimpleHTTP
<br>
<br>*Main> :i WebT
<br>newtype WebT m a = WebT {unWebT :: m (Result a)}
<br> -- Defined in HAppS.Server.SimpleHTTP
<br>instance [overlap ok] (Monad m) => Monad (WebT m)
<br> -- Defined in HAppS.Server.SimpleHTTP
<br>
<br>*Main> :i Result
<br>data Result a
<br> = NoHandle | Ok (Response -> Response) a | Escape Response
<br> -- Defined in HAppS.Server.SimpleHTTP
<br>instance [overlap ok] (Show a) => Show (Result a)
<br> -- Defined in HAppS.Server.SimpleHTTP
</p>
<p>The controller function is a list of ServerPartTs, which are handlers that
accept an HTTP request and return a response. (The boolean argument determines whether or not we
enable a certain handler -- "stress tests" -- which is discussed later; don't worry about it for now.)
This is a bit obfuscated by the many types involved in the construction,
and if you want to be pedantic it's actually a bit more complicated than that, but you don't need to understand all
the details at this point. So, for the moment, just think about a ServerPartT as a wrapper
over a function that takes an HTTP request and returns a response.
We look at what is going on in the controller code in
<a href="/tutorial/basic-url-handling">basic url handling</a>, next.
</p>
$!
<p>Now you have a choice about what to read next.</p>
<p>If you are in a hurry to write a HAppS application without delving too much into what's going on behind the scenes,
read , which looks at what's happening in the controller code.</p>
<p>If you want to understand the HAppS type system in more detail, read <a href="understanding-happs-types">understanding HAppS types</a>.
</p>
!$