On Tue, Mar 16, 2010 at 9:51 AM, Gregory Collins
<greg@gregorycollins.net> wrote:
Michael Snoyman <
michael@snoyman.com> writes:
> I think the only piece of the puzzle missing to combine these two
> together is to have mkResources output something along the lines of:
>
> data RoutePiece = StaticPiece String | IntPiece | StringPiece
> _validRoutes :: [[RoutePiece]]
> _validRoutes =
> [ [StaticPiece "user"]
> , [StaticPiece "user", StaticPiece "find", IntPiece]
> , [StaticPiece "user", StaticPiece "name", StringPiece]
> ]
Yes, this approach smells a lot better to me: the types are types and
the data are data. Just a brainstorm: if each handler monad were to
carry its routing table around with it, you could define something like:
match :: ByteString
-> (WhateverYourWebMonadIsCalled a)
-> (WhateverYourWebMonadIsCalled a)
And write
handler = match "/foo/:bar/#int/" $ do ...
without the template haskell quasiquotation (i.e. do the checking at
runtime.) Is it always true that compile-time link checking is
possible/desirable? All of these solutions also imply that each handler
knows where it's hung on the routing table so that it can resolve
relative URLs, etc.
IMO no matter what a link-checker should be lightweight enough that you
can refactor easily without rewriting a bunch of static tables; you
should be able to move an entire "subtree" to another place in the
routing table in O(1) time.
This rabbit hole goes pretty deep though; if you're serious about the
bondage and discipline approach you'd want to ensure that you can check
query parameters; i.e. "'/foo' takes a mandatory 'bar' integer parameter
on the queryString and an optional 'sort' parameter which must be either
'asc' or 'desc'", etc. At some point I have to wonder: is the medicine
worse than the disease?
I think you have some valid points here. If anyone cares to dig back through the Yesod repo far enough, they'll find an approach very similar to this, which I replaced with the quasi-quotation approach due to the boilerplate. However, if regular can clean up the boilerplate, maybe this *is* a better approach.
Also, it seems like pairing this up with a dispatch system and a model layer would actually allow fully pluggable components, assuming we can address the "where am I hung on the tree" issue. However, I'll have to think hard to come up with an example which actually makes sense.
Michael