web-inv-route-0.1: Web/Route/Invertible/Common.hs
-- |
-- The basic routing API, sufficient for route and routing map construction.
-- There is usually no need to import this module directly as it is re-exported by most other exposed interfaces.
--
-- This package supports route construction as follows:
--
-- 1. Endpoint specification, which consists of a 'Route' /key/ and action /value/.
--
-- * Describe the parameters of each endpoint using 'Route', which is constructed by composing the @route*@ functions ('routeHost', 'routePath', 'routeMethod', 'routeQuery', etc.) using "Control.Invertible.Monoidal" operators. Typically these predicates should be specified in order for sensible routing, but you can also use 'normRoute' to reorder them automatically.
-- * Join the route with a target using @\`RouteAction\`@. This target action is the /value/ associated with the route /key/, and is usually an action to produce a response in your preferred framework (but could be anything).
-- * The 'RouteAction' should typically be assigned to a top-level variable. While the type of the @Route@ parameter can differ for each route, all action values must have the same result type.
--
-- @
-- getThing :: 'RouteAction' Int (IO Response)
-- getThing =
-- 'routePath' ("thing" *\< 'parameter') \>*
-- 'routeMethod' GET
-- \`RouteAction\` \\thingId -> do
-- return Response{..}
--
-- postThingValue :: 'RouteAction' (Int, String) (IO Response)
-- postThingValue =
-- 'routeSecure' True *\<
-- 'routePath' ("thing" *\< 'parameter' \>* "value" \>*\< 'parameter') \>*
-- 'routeMethod' POST
-- `RouteAction` \\(thingId, attribute) ->
-- set thingId attribute =<< getRequestBody
-- return Response{..}
-- @
--
-- 2. Route Map specification.
--
-- * Apply each of the 'RouteAction's in your program to 'routeCase' (or 'routeNormCase' -- see 'normRoute').
-- * Apply 'routes' to a list of the resulting 'RouteCase's to form a 'RouteMap'.
--
-- @
-- myRoutes = 'routes'
-- [ 'routeCase' getThing
-- , 'routeCase' postThingValue
-- , ..
-- ]
-- @
--
-- You can also add support for new parameter types by creating your own instances of 'Parameter'.
module Web.Route.Invertible.Common
(
-- * Route construction
Route
, routeHost
, routeSecure
, routePath
, routeMethod
, routeMethods
, routeQuery
, routeAccept
, routeAccepts
, routeCustom
, routePriority
, RouteAction(..)
, mapActionRoute
-- ** Supporting types
, Host
, Path
, IsMethod
, QueryString
, ContentType
-- ** Parser construction
, module Control.Invertible.Monoidal
, wildcard
-- ** Placeholder parameters
, RouteString
, Parameter(..)
, Parameterized
, parameter
, param
, Placeholder
-- * Forward routing
, RouteCase
, routeCase
, routeNormCase
, RouteMap
, routes
, fallbackHEADtoGET
) where
import Control.Invertible.Monoidal
import Web.Route.Invertible.String
import Web.Route.Invertible.Parameter
import Web.Route.Invertible.Placeholder
import Web.Route.Invertible.Sequence
import Web.Route.Invertible.Host
import Web.Route.Invertible.Path
import Web.Route.Invertible.Method
import Web.Route.Invertible.Query
import Web.Route.Invertible.ContentType
import Web.Route.Invertible.Route
import Web.Route.Invertible.Map.Route