Dispatch mechanism (was: Re: [hunchentoot-devel] Re: hunchentoot authorization)
Michael Weber
michaelw+tbnl at foldr.org
Sun Apr 13 10:49:13 UTC 2008
On Apr 13, 2008, at 03:21 , Cyrus Harmon wrote:
> I'd like to stay away from a full-fledged web framework ala UCW or
> weblocks
Yes. please. I use Hunchentoot primarily as a thin layer above HTTP,
which shields me from dealing with the raw bytes on the wire. Also, I
have to say I haven't seen a convincing CL web framework yet. They
all seem to be UI centric, whereas I am dealing mostly with resources.
> I'm willing to 1) make this library totally hunchentoot-specific and
> 2) if necessary propose modifications to hunchentoot that would
> facilitate the implementation of this library.
I have no problem with that. For me, the only reason to prefer
something else over HT would be if I couldn't deploy behind mod_proxy,
and then I'd probably rather write an adaptor for that situation
(FastCGI, WSGI, ...).
> In particular, the hunchentoot dispatch stuff, while flexible,
> could, I think, be improved in ways that would make the
> implementation of this library more facile.
I actually find it overly flexible. (This is perhaps another of the
"organic growth" areas.)
There are several ways to plug into the dispatcher. At the moment, I
am using this:
(defvar *toplevel-routing-table*
(let ((rt (make-instance 'ht-routing-table)))
(shiftf (get-routes rt) hunchentoot:*dispatch-table* rt)
rt))
(defmethod hunchentoot:dispatch-request ((table routing-table))
(let ((controller (find-controller table *request*)))
(handle-request controller *request*)))
However, another option for me would be to just push
(lambda ()
(hunchentoot:dispatch-request *toplevel-routing-table* *request*))
onto hunchentoot:*dispatch-table*. And I haven't even look at the
meta-dispatcher stuff and starting multiple server instances.
There's probably a way to simplify all this without losing any power
or convenience.
Cheers,
Michael
BTW: The reasons behind all this:
* I like the mappings between URLs and handlers a little more
descriptive than bare function designators, for example, to print out
the mapping or appropriate Apache config stanzas. So I use CLOS
objects. Alternatively, I could have used (:metaclass funcallable-
standard-class).
* I like to be able to rearrange URL mappings while running in
development. (make-prefix-matcher "/foo/") is a little too static for
my taste.
* I bundle several end points (handlers) together (into a
"controller"), because on their own, they don't make sense. Also, the
end points don't know anything about the URL they are mapped to.
* I can deploy a single controller several times on different URL
routes (e.g., "/~foo/...", "/~bar/...", etc.). The routing dissects
the URL and provides parameters to controller and end points.
Deploying multiple "web apps" comes for free.
* Authentication is done by Apache, for the moment, because it's
convenient and works for files served statically, too.
* Authorization is done by Apache and by controllers (for, say, DB
access), because all end points are usually subject to the same
rules. End points can do additional checks with finer granularity.
More information about the Tbnl-devel
mailing list