Wheb: The frictionless WAI Framework

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]


Wheb's a framework for building robust, high-concurrency web applications simply and effectively.


Wheb makes it easy to write plugins. Plugins can add routes, middlware, settings and even handle resource cleanup on server shutdown. Named routes allow plugins to dynamically generate their routes at runtime based on settings.

Examples of plugins:

Wheb in action:

import           Web.Wheb
import           Data.Text.Lazy (pack)

main :: IO ()
main = do
  opts <- genMinOpts $ do
     addGET "home" rootPat $ (text (pack "Hi!"))
     addGET "about" ("about" </> "something") $ html (pack "<html><body><h1>About!</h1></body></html>")
  runWhebServer opts

Bigger example (Stateful.hs):

Wheb makes it easy to share a global context and handle requests statefully. The Wheb monad is both a Reader and a State Monad allowing you to seperate thread-safe resources.

Below is an example of site that naively counts the non-unique hits across all pages. MyApp is our Reader's type and MyHandlerData is our State's type. MyApp is shared across requests while MyHandlerData is thread specific with a starting state given in options. We have a middleware that intercepts the request, safely increments the shared resource TVar and sets our MyHandlerData to the correct count before it reaches our handler. We use a TVar in the Global context because any state changes to the handler state will not affect other requests.

 import           Control.Concurrent.STM
 import           Control.Monad.IO.Class
 import           Data.Monoid
 import           Data.Text.Lazy (Text, pack)
 import           Web.Wheb

 data MyApp = MyApp Text (TVar Int)
 data MyHandlerData = MyHandlerData Int

 counterMw :: MonadIO m => WhebMiddleware MyApp MyHandlerData m
 counterMw = do
   (MyApp _ ctr) <- getApp
   number <- liftIO $ atomically $ do
           num <- readTVar ctr
           writeTVar ctr (succ num)
           return num
   putHandlerState (MyHandlerData number)
   return Nothing

 homePage :: WhebHandler MyApp MyHandlerData
 homePage = do
   (MyApp appName _)   <- getApp
   (MyHandlerData num) <- getHandlerState
   html $ ("<h1>Welcome to" <> appName <>
           "</h1><h2>You are visitor #" <> (spack num) <> "</h2>")

 main :: IO ()
 main = do
   opts <- generateOptions $ do
             startingCounter <- liftIO $ newTVarIO 0
             addWhebMiddleware counterMw
             addGET (pack ".") rootPat $ homePage
             return $ (MyApp "AwesomeApp" startingCounter, MyHandlerData 0)
   runWhebServer opts


Change log None available
Dependencies base (>=4.7 && <4.8), blaze-builder (>=0.3 && <0.4), bytestring (>=0.10 && <0.11), case-insensitive (>=1.2 && <1.3), containers (>=0.5 && <0.6), cookie (>=0.4 && <0.5), http-types (>=0.8 && <0.9), mtl (>=2.1 && <2.3), pwstore-fast (>=2.4 && <2.5), stm (>=2.4 && <2.5), text (>=1.0 && <1.2), time (>=1.4 && <1.5), transformers (>=0.4 && <0.5), unix (>=2.7 && <2.8), uuid (>=1.3 && <1.4), wai (>=3.0 && <3.1), wai-extra (>=3.0 && <3.1), wai-websockets (>=3.0 && <3.1), warp (>=3.0 && <3.1), web-routes (>=0.27 && <0.28), websockets (>=0.8 && <0.9) [details]
License BSD-3-Clause
Author Kyle Hanson
Maintainer me@khanson.io
Category Web
Home page https://github.com/hansonkd/Wheb-Framework
Source repo head: git clone git://github.com/hansonkd/Wheb-Framework.git
Uploaded by hansonkd at 2014-08-03T17:19:36Z




Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees