[web-devel] More power, more configurable subsites

Michael Snoyman michael at snoyman.com
Fri Jan 21 07:51:08 CET 2011

Hi Matt (and the whole web-devel list),

Now that Warp is out, and now that the Hamlet decisions have been
made, I can (finally) start focusing on yesod-core. Most of the
changes we want are already made I think, there are only two open
issues that I'm aware of:

* Proper request body parsing[1], which is *almost* done.
* Disabling sessions for subsites[2]

On the second point, I want to broaden our scope: I want to make it
possible to run a full WAI application as a subsite. I'll give my
current use case: I just wrote a fully-featured wai-app-static
application, which takes care of redirecting from "/foo/directory" to
"/foo/directory/" and other such things. Now, let's say I have a
directory named "my.folder" or a file named "file". In Yesod, the URL
cleaning will remove the trailing slash from the former, and add the
trailing slash to the latter. However, wai-app-static will do the
exact opposite, resulting in an infinite redirect loop.

One possible solution to this predicament is to hard-code /static as a
special prefix, and not do URL cleaning. But this is a horrible, ugly,
evil hack that makes unicorns cry and babies vomit (trust me, I have
two kids, you don't want to know what happened hear after I added that
commit). What we *really* want is to give subsites much more control
over their execution. As the Yesod dispatch functions are written
right now, that's not really possible: we do all path cleanup first
and then start routing.

So here is a possible proposal for how Yesod dispatch should work:

* Break up the pathinfo (/static/directory/) into pieces (["static",
"directory", ""], the empty string at the end indicates a trailing
* Dispatch to subsites only. In other words, we'll keep a list of
subsite prefixes separate from other routes, and check those against
the unmodified pieces.
* If there are any matches, we strip out the relevant prefix from the
pieces and pass off control to the subsite.
* Subsites created with normal Yesod functions (mkYesodSub) will then
go right back into the dispatch function, but now the specific
settings for that subsite will be in place. This means that they can
control how cleanup is done, whether sessions are on, etc.
* You can also write your own subsite code directly and bypass Yesod's
dispatch system. This will also make it possible to write a
appToSubSite function so that plain WAI applications can be included
directly. (I'm hoping that with the release of Warp, there will be
more non-Yesod WAI apps out there.)

I haven't looked at implementing this yet, but it doesn't sound too
hard. I wanted to ask what you thought about how this would interact
with your more modular subsite code already.

One other thing that comes up as related: Aristid Breitkreuz emailed
me and asked why Yesod is a typeclass and not a record type. I gave an
answer[3], but I wouldn't mind other people looking into it as well.
I'm starting to think about using the records approach on the
YesodSubSite typeclass at least and see how that works out. But I have
not given this much thought, and this is really an orthogonal- albeit
related- question.


[1] http://wiki.yesodweb.com/Proper%20request%20body%20parsing
[2] https://github.com/snoyberg/yesod/issues#issue/24
[3] http://wiki.yesodweb.com/Yesod%20as%20typeclass%20or%20record

More information about the web-devel mailing list