Spock - Hello World
This literate haskell file demonstrates the most basic web application you can write with Spock. A copy of this runnable file is available here. You may run it via stack with the following command:
stack --resolver lts-9.14 runghc --package Spock SpockHello.lhs
Extensions
{-# LANGUAGE OverloadedStrings #-}
Imports
import Web.Spock
( SpockM
, runSpock
, spock
, get
, root
, text
)
SpockM |
type alias to Spock’s route definition monad |
runSpock |
runs a Spock app |
spock |
builds a runnable Spock app given a config and the app definition |
get |
builds a route handler for HTTP GETs |
root |
alias for the root route - i.e. “/” |
text |
sends text as the response body. Content-Type is set to “text/plain” |
import Web.Spock.Config
( PoolOrConn(PCNoDatabase)
, defaultSpockCfg
)
PoolOrConn |
sum type that we can utilize to let Spock manage database connections |
PCNoDatabase |
value that lets Spock know that we do not intend for it to manage DB connections |
defaultSpockCfg |
function that builds a Spock config with some default values |
Data types
data AppSession = EmptySession
data AppState = EmptyState
AppSession represents the data that we wish to persist across a session. e.g. whether a user is signed in, their email address, basic profile info, etc.
AppState represents the data that will be available to all our route handlers in Spock. e.g. configuration parameters set at application startup time - logging level, service locations, etc.
These two data types both have a single empty constructor for now since we will not be making use of Sessions or State.
Web application definition
webapp :: SpockM () AppSession AppState ()
webapp = do
get root (text "Hello stranger!")
Note the first and last type parameters to SpockM
— the first parameter is the type of database pool/connection, which in our case is ()
since we told Spock that we do not wish for it to manage any such resource. The last parameter is the return type of our web application, which is ()
since we do not expect our web application to end.
Our webapp consists of a single route: GET /
returns “Hello stranger”. Try it out by visiting http://localhost:5000/
Main
main :: IO ()
main = do
defConfig <- defaultSpockCfg EmptySession PCNoDatabase EmptyState
runSpock 5000 (spock defConfig webapp)
We build the default Spock configuration by passing 3 values to the function defaultSpockCfg
— the initial session value, database pool/connection management value, and initial app state.
Finally, we assemble the web application via spock config webapp
and tell Spock to run it on port 5000.
Note: By default, Spock listens on all interfaces.
Exercises
(Easy) Add a route to
webapp
that handlesGET /ohai
and responds with the text “O hai!”(Medium) Add a route to
webapp
that handlesPOST /ohai
and responds with the text “O hai postie!”- You can test this via
curl -X POST http://localhost:5000/ohai
- You can test this via