
I looked around, but could not find a lot of routing packages for WAI. There is wai-routes, but QuasiQuote makes me nervous. So, I hacked together a very simple router (attached). It works, though it is not efficient for large routing tables (it just does a linear scan over all possible routes in the worst case). I'm curious: (a) what are other people using? (b) are there glaringly stupid things I've done in my code? Thanks :) -- Stephen Paul Weber, @singpolyma See http://singpolyma.net for how I prefer to be contacted edition right joseph

On Sat, Mar 17, 2012 at 11:06 AM, Stephen Paul Weber < singpolyma@singpolyma.net> wrote:
I looked around, but could not find a lot of routing packages for WAI. There is wai-routes, but QuasiQuote makes me nervous.
So, I hacked together a very simple router (attached). It works, though it is not efficient for large routing tables (it just does a linear scan over all possible routes in the worst case).
I'm curious: (a) what are other people using? (b) are there glaringly stupid things I've done in my code?
Thanks :)
I use plain case expression to do routing for my simple wai applications, ghc's desugar can make it more efficent than linear scan, the code is like this: case (requestMethod req, pathInfo req) of ("GET", []) -> index ("GET", ["object", pk]) -> getObject pk ("POST", ["object", pk]) -> jsonBody >>= updateObject pk _ -> bad status404 "no route match"
-- Stephen Paul Weber, @singpolyma See http://singpolyma.net for how I prefer to be contacted edition right joseph
_______________________________________________ web-devel mailing list web-devel@haskell.org http://www.haskell.org/mailman/listinfo/web-devel

you might be interested in looking at the routing code in scotty,
which has some extra features.
https://github.com/xich/scotty
On Sat, Mar 17, 2012 at 6:02 AM, yi huang
On Sat, Mar 17, 2012 at 11:06 AM, Stephen Paul Weber
wrote: I looked around, but could not find a lot of routing packages for WAI. There is wai-routes, but QuasiQuote makes me nervous.
So, I hacked together a very simple router (attached). It works, though it is not efficient for large routing tables (it just does a linear scan over all possible routes in the worst case).
I'm curious: (a) what are other people using? (b) are there glaringly stupid things I've done in my code?
Thanks :)
I use plain case expression to do routing for my simple wai applications, ghc's desugar can make it more efficent than linear scan, the code is like this:
case (requestMethod req, pathInfo req) of ("GET", []) -> index ("GET", ["object", pk]) -> getObject pk ("POST", ["object", pk]) -> jsonBody >>= updateObject pk _ -> bad status404 "no route match"
-- Stephen Paul Weber, @singpolyma See http://singpolyma.net for how I prefer to be contacted edition right joseph
_______________________________________________ web-devel mailing list web-devel@haskell.org http://www.haskell.org/mailman/listinfo/web-devel
-- http://www.yi-programmer.com/blog/
_______________________________________________ web-devel mailing list web-devel@haskell.org http://www.haskell.org/mailman/listinfo/web-devel

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Somebody claiming to be Greg Weber wrote:
you might be interested in looking at the routing code in scotty, which has some extra features.
This also looks interesting. I will have to play with it some. - -- Stephen Paul Weber, @singpolyma See http://singpolyma.net for how I prefer to be contacted edition right joseph -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAEBCAAGBQJPZTD8AAoJENEcKRHOUZze3uUP/1wdDj1ETyay7Q9b8aZGAsXx 1ljPZzACvZll90E6Vp/8iDz+umkz+sIjBz9QMFLzi1v7+CdSwo00afK/NqQiaA4w eJJQzTj39qB99r1vWrVLzitiH3E9a1FyYWuKlhL5Lua98o+W8/ZHf69I50bX2/9m pU3U/xcCsfBgeClgJqr7OI9KAFiOX34shNf9iT0UXaNfG2nq6Laj7xY3eRe9hbHw L7SPwfO7+0oOYZXdCqx8l5BL+nuDtHBUD3N1QCjz5faFXTEG/tU/eJpA+drpP67c C1SzGM7mTeDBsZ7xpzKa/XvViYd53kd3i22Mw5HmBTkFj5h23Srq4byOUQKpdV0g pft2B1q7gWI+xhxzg++juHtEGQ9RnlKPhLnkFRE+UdZuhcYrFUzLVFIra1w58MH+ IBvvq2dpkBpX6lBm0Hl5JS+lHnVeDw8nQxpwDuc8rKKWfNENPw4AgyfdNrv2VFsN CEZZjbYgeor+msc3QNRTl2RlY00yhukbnOdHEtW0CqTvSYcgeRBug3kDaJOgOXxf xNiN8TnyQX0Pz5JvPLysW9BcIDdTZbiZVC6avLF/LXRb6eaVUL2pMwF4apTwYpLI QlJ+T5pDfmPtoPkQTBTZqvTPpqY73059fJPhZOzGxaQl3Q1hOq8K5p2sN+B9h32s Pvl1a2K2M84Dsm6wKhTP =azR+ -----END PGP SIGNATURE-----

On Sat, Mar 17, 2012 at 3:32 PM, Greg Weber
you might be interested in looking at the routing code in scotty, which has some extra features.
Routing there is also O(n) in the number of handlers, if I'm reading the
code right. If you can't match a URL to a Handler in less than O(log n) in
the number of handlers, you're doing it wrong. Programs that are growing in
size usually do so because they are actually being used, so as your need
for the framework to scale grows, you have to waste time re-engineering
efficient routing into your existing program, and usually in a panic or
crisis situation. Both Snap and Yesod do this right.
G
--
Gregory Collins

On Sun, Mar 18, 2012 at 2:21 PM, Gregory Collins
On Sat, Mar 17, 2012 at 3:32 PM, Greg Weber
wrote: you might be interested in looking at the routing code in scotty, which has some extra features.
Routing there is also O(n) in the number of handlers, if I'm reading the code right. If you can't match a URL to a Handler in less than O(log n) in the number of handlers, you're doing it wrong. Programs that are growing in size usually do so because they are actually being used, so as your need for the framework to scale grows, you have to waste time re-engineering efficient routing into your existing program, and usually in a panic or crisis situation. Both Snap and Yesod do this right.
G -- Gregory Collins
_______________________________________________ web-devel mailing list web-devel@haskell.org http://www.haskell.org/mailman/listinfo/web-devel
The code at play for Yesod is in the Yesod.Routes.Dispatch[1] module. The source[2] is highly commented Literate Haskell, which goes into details of our algorithm, which takes advantage of vectors for an initial O(1) whittling down of possible routes, followed by a series of Map lookups[3], and finally a linear traversal of the remaining routes to address parsing of dynamic pieces. If you avoid overlapping routes (highly recommended), then the last stage will always have either 0 or 1 matches. I purposely put this code into a separate module without any TH or Yesod dependencies so that it could be used by others for route dispatch. I don't believe there's anything really Yesod-specific about it, so it might be a good fit for scotty. I've never dug through the routing code for Snap; what's the dispatch algorithm used? Michael [1] http://hackage.haskell.org/packages/archive/yesod-routes/0.0.1/doc/html/Yeso... [2] http://hackage.haskell.org/packages/archive/yesod-routes/0.0.1/doc/html/src/... [3] It might be worth switching to a HashMap here, if someone can put together a good benchmark I'd love to see the results.

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Somebody claiming to be Michael Snoyman wrote:
On Sun, Mar 18, 2012 at 2:21 PM, Gregory Collins
you might be interested in looking at the routing code in scotty, which has some extra features.
Routing there is also O(n) in the number of handlers
The code at play for Yesod is in the Yesod.Routes.Dispatch[1] module. The source[2] is highly commented Literate Haskell, which goes into details of our algorithm, which takes advantage of vectors for an initial O(1) whittling down of possible routes, followed by a series of Map lookups[3], and finally a linear traversal of the remaining routes to address parsing of dynamic pieces. If you avoid overlapping routes (highly recommended), then the last stage will always have either 0 or 1 matches.
Hmm, this also looks interesting. Though it's more of a backend algorithm for a router than a router itself (which is fine). It might be interesting to patch support into Scotty (definitely possible). I wonder what the overhead is (ie: approximately how many routes one needs before the fancy algorithm is faster). - -- Stephen Paul Weber, @singpolyma See http://singpolyma.net for how I prefer to be contacted edition right joseph -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAEBCAAGBQJPZhd6AAoJENEcKRHOUZzefwQQAJyxhr9cz0HD8vjZTqPURFBL mTZPITi/3MLlxTS+fFPLe0G3QAG3ZgjGkGsx3TQ80kx1X1os9D/BoGHWs2Vi1asv G/7N5Q7GzafrguhgJOReTLkOwztJwVwoB9YBGWCnXd3Ml+ass8pZokvvjwGwt4Ta DVDdP1VAisjSWKB/v5OO3Yxk5l0ekr9Ivml2JiqxnKwQ+E6wRWl7bpVZuHPXU/jD xXwf3PUFtLbKNuL4BLQfr94qaeIVAWObYUnTL92jc+qHL3+QzbDG9vKLNvT1u7WY Wf1WWyRZ3OcrfdhiQyRz8JuhBfjNPxTigc5jmZAhBJ8KhKzGmXChsb/ItD7Dn/BK NHfG9K2Z7bBRkuOBDcnLp25+F6aACugn/sQvKIYd9+6wdyaRNme4xFTg42T/KvYk vTIrUygqZVApjuzWvNEG1jvu1rLzRcfseIG1FVBR2btFWBiRth0HI3RTxZB6pY0l sfDf5Y79cVSaAvcgvvVC1YKZI1Vpp2zVD/5Z0nVkNz7+q8ARfnLunmsDlvtRVdFo vHCuNbYd5Clm66X8ZzCJhRFmpDNwmZo5JOxkxZ8OVxaZZlV/kS5xwlB7a0yiC1ef LC90P0I+rq8sgDlOMnKesKdpY3lJLsGX+rGWUX6cDmQPp5M1HQvJ0LbzsC9t7UuN x4uri5wvjvsHxC7vRQ3u =ZGsM -----END PGP SIGNATURE-----

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Somebody claiming to be yi huang wrote:
On Sat, Mar 17, 2012 at 11:06 AM, Stephen Paul Weber < singpolyma@singpolyma.net> wrote: I use plain case expression to do routing for my simple wai applications, ghc's desugar can make it more efficent than linear scan
Really? That's interesting
the code is like this:
case (requestMethod req, pathInfo req) of ("GET", []) -> index ("GET", ["object", pk]) -> getObject pk ("POST", ["object", pk]) -> jsonBody >>= updateObject pk _ -> bad status404 "no route match"
Hmm, that may indeed solve many of my use cases, and is very nice looking. I assume this only works with -XOverloadedStrings, and that's why you can pattern match on Data.Text? - -- Stephen Paul Weber, @singpolyma See http://singpolyma.net for how I prefer to be contacted edition right joseph -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAEBCAAGBQJPZTArAAoJENEcKRHOUZzedaEP/jzUSmrvTm6fWVpQOl9AOZoP UebR3RdwqUGXNXE7dPGgSkdihRsD8h0ToOHziNpphj7fVDLY216zSes6rL4GGZIq PL2HD6j0tW6GK/kQLwgYCoxNIy6v/E9FDppfuUDNNnPqloSIH4cTfvMVTLaVH434 yCR7bv202NckBeahmoFz/1xQh8pANijsrozNqz8vEifmzGbSt72/FqQ0d6oogOGk QEQFTy9ctjf1740paual/pn0v+ESIuTQ+0yxJ0wiaxowmaCHZdkqiTK3ZTZLpaB9 teqjrdGpxaYG6X9Ldv6ZzztphvrlfS57daBidxoelG8jaLX+f7SeNnbg8v9PX/31 JXJmEkkG5Nn2hkWUqw+9sNKcpJRzWqyx/hQyhPBKiPYGDtvyY0aB1UT7hoATzCPF QhPTVlyabx/53aKz6c7tXKrQGmRSQ1G163kJQzU682khhLUTvqL1u0ZFeEfdC3Bm bOo+K9+32pOBFCPee51pgy6cg0SRk/Z+8miGz6bzh2EJ+iaxGX2KkhlXFI+1G5Hu Cdnocehs0b1o9McAnHqAAgkrUov5HmY4akDkhzfbgP+4OgXtZn3j3nFlkU/MP46R Pi+ZQvjTVGtD0AEIwh5X1EKPYWx8cGZSIGTHxPTP3uZav59urLrYBmk/VcTTOWls Zt9s88iEIJ8Vgvm8V6P7 =i7R9 -----END PGP SIGNATURE-----
participants (5)
-
Greg Weber
-
Gregory Collins
-
Michael Snoyman
-
Stephen Paul Weber
-
yi huang