[web-devel] Type-safe URL handling

Michael Snoyman michael at snoyman.com
Tue Mar 16 13:28:43 EDT 2010


On Tue, Mar 16, 2010 at 9:51 AM, Gregory Collins <greg at gregorycollins.net>wrote:

> Michael Snoyman <michael at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/web-devel/attachments/20100316/58e8f20d/attachment.html


More information about the web-devel mailing list