Readme for hack2-2014.11.17

Hack2: a Haskell Webserver Interface (V2)

Hack2 is a port of Ruby's Rack webserver interface.

Introduction

Idea

Separation of concerns:

Design

type Application = Env -> IO Response

Demo

{-# LANGUAGE OverloadedStrings #-}

import Hack2
import Hack2.Contrib.Response (set_body_bytestring)
import Hack2.Handler.SnapServer

app :: Application
app = \env -> 
  return $ 
    Response 
      200 [ ("Content-Type", "text/plain") ] "Hello World"

main = run app

Spec

The Environment

The Response

Properties

1 minute tutorial

update cabal

cabal update

install hack

cabal install hack2

install some hack helpers

cabal install hack2-contrib

pick a backend

cabal install hack2-handler-snap-server

Create a Hack app

put the following code in Main.hs

{-# LANGUAGE OverloadedStrings #-}

import Hack2
import Hack2.Contrib.Response (set_body_bytestring)
import Hack2.Handler.SnapServer
import Data.Default (def)

app :: Application
app = \env -> 
  return $ 
    set_body_bytestring "Hello World 2" $ 
      def { headers = [ ("Content-Type", "text/plain") ] }

main = run app

run

runghc Main.hs

It should be running on http://127.0.0.1:3000 now.

Middleware

demo usage of middleware

put the following in Main.hs. This code uses the URLMap middleware to route both /hello and /there to the say application.

{-# LANGUAGE OverloadedStrings #-}

import Hack2
import Hack2.Contrib.Response (set_body_bytestring)
import Hack2.Handler.SnapServer
import Data.Default (def)

import Data.ByteString.Char8 (pack)
import Hack2.Contrib.Utils (empty_app)
import Hack2.Contrib.Middleware.URLMap


say :: Application
say = \env -> return $ set_body_bytestring (pack $ show env) def

app :: Application
app = url_map [("/hello", say), ("/there", say)] empty_app

main = run app

create a middleware

inside Hack2.hs:

type Middleware = Application -> Application

since Haskell has curry, middleware api can be of type

Anything -> Application -> Application

just pass an applied middleware into a chain.

finally the source code of Config.hs:

module Hack2.Contrib.Middleware.Config (config) where

import Hack2

config :: (Env -> Env) -> Middleware
config alter app = \env -> app (alter env)

Use the middleware stack

From Hack2.Contrib.Utils:

-- usage: use [content_type, cache] app
use :: [Middleware] -> Middleware
use = reduce (<<<)

Handlers

Once an application is written using Hack2, it should work on any web server that provides a Hack2 handler.

A handler should expose at least one function of type:

run :: Application -> IO ()

Upgrade

With every new release, any library links to Hack2 should be recompiled against the new version, usually as simple as:

cabal install linked_lib --reinstall

Discuss:Web programming with Haskell