nested-routes: Declarative, compositional Wai responses
A method to writing Wai responses
This library attempts to make it easier to write nice Wai response handlers by giving us a Sinatra/ Scotty-like syntax for declaring HTTP-verb oriented routes, in addition to file-extension handling and rose-tree like composition. Not only do we have literal route specification, like Scotty & Spock, but we can also embed Attoparsec parsers and Regular Expressions directly in our routes, with our handlers reflecting their results. As an example:
router :: Application
router = route handlers
where
handlers = do
handle o
(get $ text "home")
Nothing
handle ("foo" </> "bar")
(get $ text "foobar") $ Just $
handle (p ("baz", double) </> o)
(\d -> get $ text $ LT.pack (show d) <> " bazs")
Nothing
handle (p ("num",double) </> o)
(\d -> get $ text $ LT.pack $ show d) $ Just $ do
handle "bar"
(\d -> get $ do
text $ (LT.pack $ show d) <> " bars")
json $ (LT.pack $ show d) <> " bars!")
Nothing
handle (r ("email", mkRegex "(^[-a-zA-Z0-9_.]+@[-a-zA-Z0-9]+\\.[-a-zA-Z0-9.]+$)") </> o)
(\d e -> get $ textOnly $ (LT.pack $ show d) <> " " <> (LT.pack $ show e)The route specification syntax is a little strange right now - l specifies
a "literal chunk" of a handlable url (ie - l "foo" </> l "bar" </> o would
represent the url /foo/bar), while p represents a "parsable" url chunk,
which expects a pair - the left element being merely a reference name for the
parser during internal plumbing, and the right being the actual Parser. o represents
the end of a url string, and can be used alone in a handler to capture requests
to the root path.
Each route being handled needs some kind of content. For every parsed url chunk,
the route expects a function
of arity matching 1-for-1 with the parsed contents. For example, d -> ... in the
demonstration above is such a function, where d :: Double.
Internally, we match against both the file extension and Accept headers in the HTTP request - the Accept header may override the file extension.
When we test our application:
λ> curl localhost:3000/ -H "Accept: text/plain, */*" ↪ "home"
requests may end with index
λ> curl localhost:3000/index -H "Accept: text/plain, */*" ↪ "home"
and specify the file extension
λ> curl localhost:3000/index.txt -H "Accept: text/plain, */*" ↪ "home"
each responding with the "closest" available file type
λ> curl localhost:3000/index.html -H "Accept: text/html, */*" ↪ "home"
λ> curl localhost:3000/foo/bar -H "Accept: text/plain, */*" ↪ "foobar"
λ> curl localhost:3000/foo/bar.txt -H "Accept: text/plain, */*" ↪ "foobar"
λ> curl localhost:3000/foo/bar/5678.5678 -H "Accept: text/plain, */*" ↪ "5678.5678 bazs"
λ> curl localhost:3000/1234.1234 -H "Accept: text/plain, */*" ↪ "1234.1234"
λ> curl localhost:3000/2e5 -H "Accept: text/plain, */*" ↪ "200000.0"
λ> curl localhost:3000/1234.1234/bar -H "Accept: text/plain, */*" ↪ "1234.1234 bars"
Modules
[Index]
- Web
- Routes
- Web.Routes.Nested
- Web.Routes.Nested.FileExtListener
- Web.Routes.Nested.FileExtListener.Blaze
- Web.Routes.Nested.FileExtListener.Builder
- Web.Routes.Nested.FileExtListener.ByteString
- Web.Routes.Nested.FileExtListener.Cassius
- Web.Routes.Nested.FileExtListener.Clay
- Web.Routes.Nested.FileExtListener.Json
- Web.Routes.Nested.FileExtListener.Julius
- Web.Routes.Nested.FileExtListener.Lucid
- Web.Routes.Nested.FileExtListener.Lucius
- Web.Routes.Nested.FileExtListener.Text
- Web.Routes.Nested.FileExtListener.Types
- Web.Routes.Nested.Types
- Web.Routes.Nested.VerbListener
- Web.Routes.Nested.FileExtListener
- Web.Routes.Nested
- Routes
Downloads
- nested-routes-1.0.0.1.tar.gz [browse] (Cabal source package)
- Package description (as included in the package)
Maintainer's Corner
For package maintainers and hackage trustees
Candidates
- No Candidates
| Versions [RSS] | 0.0.1, 0.0.1.1, 0.0.2, 0.0.3.1, 0.1, 0.1.1, 0.2, 0.2.0.1, 0.2.0.2, 0.2.1, 0.2.2, 0.2.2.1, 0.2.2.2, 0.3, 0.3.1, 0.3.2, 0.3.2.1, 1.0, 1.0.0.1, 2.0.0, 2.0.1, 2.1.0, 2.2.0, 3.0.0, 3.0.0.1, 3.0.0.2, 3.1.0, 3.2.0, 4.0.0, 5.0.0, 6.0.0, 6.0.0.1, 6.1.0, 7.0.0, 7.1.0, 7.1.0.1, 7.1.1, 7.2.0, 7.2.1, 7.2.2, 8.0.0, 8.0.1, 8.0.2, 8.1.0, 8.2.0, 9.0.0, 9.0.0.1, 9.0.1.0, 9.0.1.1, 9.0.2, 10.0.0 (info) |
|---|---|
| Dependencies | aeson, attoparsec, base (>=4.6 && <5), blaze-html, bytestring, clay, composition, constraints, containers, http-media, http-types, lucid, mtl, poly-arity (>=0.0.4), pred-trie (>=0.1), regex-compat, semigroups, shakespeare, text, transformers, wai, wai-extra, wai-util, witherable [details] |
| License | BSD-3-Clause |
| Author | Athan Clark <athan.clark@gmail.com> |
| Maintainer | Athan Clark <athan.clark@gmail.com> |
| Category | Web |
| Source repo | head: git clone git://github.com/athanclark/nested-routes.git |
| Uploaded | by athanclark at 2015-05-09T22:39:09Z |
| Distributions | |
| Reverse Dependencies | 2 direct, 0 indirect [details] |
| Downloads | 25316 total (88 in the last 30 days) |
| Rating | (no votes yet) [estimated by Bayesian average] |
| Your Rating | |
| Status | Docs uploaded by user Build status unknown [no reports yet] |