wai-routes 0.3.1 → 0.3.2
raw patch · 6 files changed
+154/−88 lines, 6 files
Files
- README +0/−76
- README.md +81/−0
- examples/Example.hs +16/−10
- src/Network/Wai/Middleware/Routes/Handler.hs +53/−0
- src/Network/Wai/Middleware/Routes/Routes.hs +1/−0
- wai-routes.cabal +3/−2
− README
@@ -1,76 +0,0 @@-Wai Routes (wai-routes-0.3.1)-==============================--This package provides typesafe URLs for Wai applications.--Features:- - Automatic generation of Route boilerplate using TH- - Easy Nested Routes- - Sitewide Master datatype which is passed to all handlers- and can be used for persistent data (like DB connections)- - RouteM monad that makes it easy to compose an application- with multiple routes and middleware.- - Handlers can abort processing and pass control to the next- application in the wai stack--It depends on yesod-routes package for the TH functionality (but not the rest of yesod). The aim is to provide a similar level of typesafe URL functionality to Wai applications as is available to Yesod applications.---Example Usage-=============--The following builds a simple JSON service (using Aeson for JSON conversion)--- {-# LANGUAGE OverloadedStrings, TypeFamilies #-}-- import Network.Wai- import Network.Wai.Middleware.Routes-- import Data.IORef-- -- The Site Argument- data MyRoute = MyRoute (IORef DB)-- -- Generate Routes- mkRoute MyRoute [parseRoutes|- / UsersR GET- /user/#Int UserR:- / UserRootR GET- /delete UserDeleteR POST- |]-- -- Define Handlers- -- All Users Page- getUsersR :: Handler MyRoute- getUsersR (MyRoute dbref) request = ...- -- Single User Page- getUserRootR :: Int -> Handler MyRoute- getUserRootR userid (MyRoute dbref) request = ...- -- Delete Single User- postUserDeleteR :: Int -> Handler MyRoute- postUserDeleteR userid (MyRoute dbref) request = ...-- -- Define Application using RouteM Monad- myApp = do- db <- liftIO $ newIORef mydb- route (MyRoute db)- setDefaultAction $ staticApp $ defaultFileServerSettings "static"-- -- Run the application- main :: IO ()- main = toWaiApp myApp >>= run 8080---Changelog-=========--0.1 : Intial release-0.2 : Updated functionality based on yesod-routes package-0.2.1 : Changed license to MIT-0.2.2 : Fixed license information in hs and cabal files-0.2.3 : Implemented a better showRoute function. Added blaze-builder as a dependency-0.2.4 : Put an upper bound on yesod-routes version as 1.2 breaks API compatibility-0.3.0 : yesod-routes 1.2 compatibility. Abstracted request data. Created `runNext` which skips to the next app in the wai stack-0.3.1 : Removed internal 'App' synonym which only muddied the types. Added common content types for convenience.-
+ README.md view
@@ -0,0 +1,81 @@+Wai Routes (wai-routes-0.3.2)+==============================++[](https://travis-ci.org/ajnsit/wai-routes)++This package provides typesafe URLs for Wai applications.++Features:+ - Automatic generation of Route boilerplate using TH+ - Easy Nested Routes+ - Sitewide Master datatype which is passed to all handlers+ and can be used for persistent data (like DB connections)+ - RouteM monad that makes it easy to compose an application+ with multiple routes and middleware.+ - HandlerM monad that makes it easy to build a Handler+ with access to Request data and Master datatype+ - Handlers can abort processing and pass control to the next+ application in the wai stack++It depends on yesod-routes package for the TH functionality (but not the rest of yesod). The aim is to provide a similar level of typesafe URL functionality to Wai applications as is available to Yesod applications.+++Example Usage+=============++The following builds a simple JSON service (using Aeson for JSON conversion)+++ {-# LANGUAGE OverloadedStrings, TypeFamilies #-}++ import Network.Wai+ import Network.Wai.Middleware.Routes++ import Data.IORef++ -- The Site Argument+ data MyRoute = MyRoute (IORef DB)++ -- Generate Routes+ mkRoute MyRoute [parseRoutes|+ / UsersR GET+ /user/#Int UserR:+ / UserRootR GET+ /delete UserDeleteR POST+ |]++ -- Define Handlers+ -- All Users Page+ getUsersR :: Handler MyRoute+ getUsersR (MyRoute dbref) request = ...+ -- Single User Page+ getUserRootR :: Int -> Handler MyRoute+ getUserRootR userid = ...+ -- Delete Single User+ postUserDeleteR :: Int -> Handler MyRoute+ postUserDeleteR userid = ...++ -- Define Application using RouteM Monad+ myApp = do+ db <- liftIO $ newIORef mydb+ route (MyRoute db)+ setDefaultAction $ staticApp $ defaultFileServerSettings "static"++ -- Run the application+ main :: IO ()+ main = toWaiApp myApp >>= run 8080+++Changelog+=========++0.1 : Intial release+0.2 : Updated functionality based on yesod-routes package+0.2.1 : Changed license to MIT+0.2.2 : Fixed license information in hs and cabal files+0.2.3 : Implemented a better showRoute function. Added blaze-builder as a dependency+0.2.4 : Put an upper bound on yesod-routes version as 1.2 breaks API compatibility+0.3.0 : yesod-routes 1.2 compatibility. Abstracted request data. Created `runNext` which skips to the next app in the wai stack+0.3.1 : Removed internal 'App' synonym which only muddied the types. Added common content types for convenience.+0.3.2 : Added HandlerM Monad which makes it easier to build Handlers+
examples/Example.hs view
@@ -3,6 +3,7 @@ import Network.Wai import Network.Wai.Middleware.Routes+import Network.Wai.Middleware.Routes.Handler import Network.Wai.Middleware.Routes.ContentTypes import Network.Wai.Application.Static import Network.Wai.Handler.Warp@@ -50,9 +51,15 @@ jsonHeaders :: ResponseHeaders jsonHeaders = [contentType typeJson] +-- Util: Fetch the database+getDB :: HandlerM MyRoute DB+getDB = do+ MyRoute dbref <- master+ liftIO $ readIORef dbref+ -- Display the possible actions getHomeR :: Handler MyRoute-getHomeR _master _req = return $ jsonOut $ M.fromList (+getHomeR = runHandlerM $ return $ jsonOut $ M.fromList ( [("description", [["Simple User database Example"]]) ,("links" ,[["home", showRoute HomeR]@@ -64,8 +71,8 @@ -- Display all the users getUsersR :: Handler MyRoute-getUsersR (MyRoute dbref) _req = do- db <- liftIO $ readIORef dbref+getUsersR = runHandlerM $ do+ db <- getDB let dblinks = map linkify db let out = M.fromList ( [("description", [["Users List"]])@@ -76,8 +83,8 @@ -- Display a single user getUserRootR :: Int -> Handler MyRoute-getUserRootR i (MyRoute dbref) _req = do- db <- liftIO $ readIORef dbref+getUserRootR i = runHandlerM $ do+ db <- getDB case ulookup i db of Nothing -> return $ jsonOut ("ERROR: User not found" :: Text) Just user -> do@@ -102,17 +109,17 @@ -- Delete a user: GET getUserDeleteR :: Int -> Handler MyRoute-getUserDeleteR _ _master _req = return $ jsonOut err+getUserDeleteR _ = runHandlerM $ return $ jsonOut err where err = ["DELETE","please use POST"]::[Text] -- Delete a user: POST postUserDeleteR :: Int -> Handler MyRoute-postUserDeleteR _ _master _req = return $ jsonOut err+postUserDeleteR _ = runHandlerM $ return $ jsonOut err where err = ["DELETE","not implemented"]::[Text] -- Demonstrate skipping routes getSkipR :: Handler MyRoute-getSkipR _master = runNext+getSkipR = runHandlerM next -- Initial database initdb :: [User]@@ -130,8 +137,7 @@ |] getSkippedR :: Handler MySkippedRoute-getSkippedR _req _master =- return $ jsonOut err+getSkippedR = runHandlerM $ return $ jsonOut err where err = ["SKIPPED","skipped route"]::[Text] -- The application that uses our route
+ src/Network/Wai/Middleware/Routes/Handler.hs view
@@ -0,0 +1,53 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{- |+Module : Network.Wai.Middleware.Routes.Handler+Copyright : (c) Anupam Jain 2013+License : MIT (see the file LICENSE)++Maintainer : ajnsit@gmail.com+Stability : experimental+Portability : non-portable (uses ghc extensions)++Provides a HandlerM Monad that makes it easy to build Handlers+-}+module Network.Wai.Middleware.Routes.Handler+ ( HandlerM() -- | A Monad that makes it easier to build a Handler+ , runHandlerM -- | Run a HandlerM to get a Handler+ , request -- | Access the request data+ , master -- | Access the master datatype+ , next -- | Run the next application in the stack+ )+ where++import Data.Conduit (ResourceT)+import Network.Wai (Request, Response)+import Control.Monad.Reader (ReaderT, ask, runReaderT, MonadReader, MonadIO, lift)++import Network.Wai.Middleware.Routes.Routes (RequestData, Handler, waiReq, runNext)++-- | The HandlerM Monad+newtype HandlerM master a = H { extractH :: ReaderT (HandlerState master) (ResourceT IO) a }+ deriving (Monad, MonadIO, Functor, MonadReader (HandlerState master))++-- | The state kept in a HandlerM Monad+data HandlerState master = HandlerState+ { getMaster :: master+ , getRequestData :: RequestData+ }++-- | "Run" HandlerM, resulting in a Handler+runHandlerM :: HandlerM master Response -> Handler master+runHandlerM h m r = runReaderT (extractH h) (HandlerState m r)++-- | Get the master+master :: HandlerM master master+master = ask >>= return . getMaster++-- | Get the request+request :: HandlerM master Request+request = ask >>= return . waiReq . getRequestData++-- | Run the next application+next :: HandlerM master Response+next = ask >>= H . lift . runNext . getRequestData+
src/Network/Wai/Middleware/Routes/Routes.hs view
@@ -40,6 +40,7 @@ , ParseRoute(..) -- | A `ParseRoute` instance for your site datatype is automatically generated by `mkRoute` , RouteAttrs(..) -- | A `RouteAttrs` instance for your site datatype is automatically generated by `mkRoute` + -- * Accessing Request Data , RequestData -- | An abstract representation of the request data. You can get the wai request object by using `waiReq` , waiReq -- | Extract the wai `Request` object from `RequestData` , nextApp -- | Extract the next Application in the stack
wai-routes.cabal view
@@ -1,5 +1,5 @@ Name: wai-routes-Version: 0.3.1+Version: 0.3.2 Synopsis: Typesafe URLs for Wai applications. Homepage: https://github.com/ajnsit/wai-routes License: MIT@@ -10,7 +10,7 @@ Cabal-Version: >=1.6 stability: Experimental Category: Network-Extra-source-files: README, examples/Example.hs+Extra-source-files: README.md, examples/Example.hs Description: Provides easy to use typesafe URLs for Wai Applications. .@@ -82,5 +82,6 @@ exposed-modules: Network.Wai.Middleware.Routes , Network.Wai.Middleware.Routes.Routes , Network.Wai.Middleware.Routes.Monad+ , Network.Wai.Middleware.Routes.Handler , Network.Wai.Middleware.Routes.ContentTypes