NodeJS¶
The server in Hyper.Node.Server
wraps the http
module in NodeJS,
and serves middleware using the Aff
monad. Here is how you can start
a Node server:
let
app =
writeStatus (Tuple 200 "OK")
:*> closeHeaders
:*> respond "Hello there!"
in runServer defaultOptions {} app
As seen above, runServer
takes a record of options, an initial
components record, and your application middleware. If you want to do
logging on server startup, and on any request handling errors, use
defaultOptionsWithLogging
.
Monad Transformers¶
You might want to use a monad transformer stack in your application, for
instance as a way to pass configuration, or to accumulate some state in
the chain of middleware. The underlying monad of Middleware
is
parameterized for this exact purpose. When running the NodeJS server
with monad transformers, you need to use runServer'
instead of the regular
runServer
, and pass a function that runs your monad and returns an Aff
value.
The following code runs a middleware using the ReaderT
monad
transformer. Note that the runAppM
function might need to be defined
at the top-level to please the type checker.
type MyConfig = { thingToSay :: String }
runAppM
:: forall e a.
ReaderT MyConfig (Aff e) a
-> Aff e a
runAppM = flip runReaderT { thingToSay: "Hello, ReaderT!" }
main :: forall e. Eff (console :: CONSOLE, http :: HTTP | e) Unit
main =
let app =
lift' ask :>>= \config ->
writeStatus statusOK
:*> closeHeaders
:*> respond config.thingToSay
in runServer' defaultOptionsWithLogging {} runAppM app
In a real-world application the configuration type MyConfig
could
hold a database connection pool, or settings read from the environment,
for example.