• ¶
    #! /usr/bin/env nix-shell
    #! nix-shell -i runhaskell -p 'ghc.withPackages(pkgs: with pkgs; [Spock])'
    
    {-# LANGUAGE OverloadedStrings #-}
    
    import Data.Monoid
        ( (<>)  -- append operator for monoids (e.g. string, list)
        )
    
    import Web.Spock
        (
  • ¶

    type alias to Spock’s route definition monad

          SpockM
  • ¶

    runs a Spock app

        , runSpock
  • ¶

    builds a runnable Spock app given a config and the app definition

        , spock
  • ¶

    builds a route handler for HTTP GETs

        , get
  • ¶

    alias for the root route - i.e. “/“

        , root
  • ¶

    sends text as the response body. Content-Type is set to “text/plain”

        , text
  • ¶
        )
    
    import Web.Spock.Config
        (
  • ¶

    Spock’s configuration type

          SpockCfg
  • ¶

    config for cross-site request forgery protection (default is False due to historical reasons)

            ( spc_csrfProtection )
  • ¶

    Sum type that we can utilize to let Spock manage database connections

        , PoolOrConn
  • ¶

    value that lets Spock know that we do not intend for it to manage DB connections

            ( PCNoDatabase )
  • ¶

    function that builds a Spock config with some default values

        , defaultSpockCfg
        )
  • ¶

    AppSession contains data that we wish to persist across a session. e.g. whether a user is signed in, their email address, basic profile info, etc. Empty for now.

    data AppSession = EmptySession
  • ¶

    AppState contains 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. Empty for now.

    data AppState = EmptyState
  • ¶
    main :: IO ()
    main = do
  • ¶

    We build the default Spock configuration by passing 3 values to defaultSpockCfg — the initial session value, DB connection management value, initial app state.

        defConfig <- defaultSpockCfg EmptySession PCNoDatabase EmptyState
  • ¶

    We override the above config so that Spock turns on CSRF protection.

        let config = defConfig { spc_csrfProtection = True }
  • ¶

    Tell Spock to run on port 5000 and pass it a configuration and webapp definition. Note: By default, Spock listens on all interfaces.

        runSpock 5000 (spock config webapp)
  • ¶

    Web application definition

    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.

    webapp :: SpockM () AppSession AppState ()
    webapp = do
  • ¶

    GET / returns “Hello stranger”. Try it out by visiting http://localhost:5000/

        get root (text "Hello stranger!")