[web-devel] Type-safe URL handling

Jeremy Shaw jeremy at n-heptane.com
Sun Mar 28 20:32:47 EDT 2010


On Fri, Mar 26, 2010 at 6:01 PM, Jeremy Shaw <jeremy at n-heptane.com> wrote:

> A variation which is more obviously hierarchical in nature:
>
> data User = User LastName FirstName
> data Section = Recent | TopRated
> data UserHomeURL = Wall Section | Profile
> data UserURL = ViewHome User UserHome
>
> Which would be used to construct urls like:
>
> /shaw/jeremy/wall/recent
> /snoyman/michael/profile
>

To expand on this slightly let's pretend you first implemented a module that
supported a single user:

data Section = Recent | TopRated
data UserHomeURL = Wall Section | Profile

And you release that as a library.

Then in another app, which supports multiple users, you want to use it. So
you create:

data User = User LastName FirstName
data UserURL = ViewHome User UserHome

That seems pretty sensible. After all the half the point of this library is
to be able to build reusable components. Because we are reusing a component,
we can not modify the UserHome portion of the URL. But we still need some
way to specify which user's home we are looking at. The above types seem
sensible for that.

You have similar structures in your photo blog app:

--------
instance Yesod PB where
    resources = [$mkResources|
/:
    GET: indexHandler
/entries/$entryId:
    GET: entry
/entries/$entryId/$filename:
    GET: media
/feed:
    GET: feed

...
------

A reasonable URL type for that might be:

data EntryId = ...
data PhotoBlogURL = BlogHome | Entry EntryId | Media EntryId FileName | Feed

Where Media has two arguments to it's constructor. You can't really factor
that out, can you? You could fake it like:

data PhotoBlogURL = BlogHome | Entry EntryId | Media (EntryId, FileName) |
Feed

But that does not really buy you anything, because when you write the Media
parser, you still have to know how many segments EntryId consumes, and how
many FileName consumes.

perhaps entryid is:

data EntryId = EntryId { year :: Int
                                     , month :: Int
                                     ,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/web-devel/attachments/20100328/328eae0f/attachment.html


More information about the web-devel mailing list