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.